blob: c2efa1c114a7ea8c3a2d870b8933fcfb134c3e3d [file]
From 13a4169b5ecb1f742de03edafd52954995d879f1 Mon Sep 17 00:00:00 2001
From: Pierre Wielders <pierre@wielders.net>
Date: Mon, 24 Oct 2022 17:41:29 +0200
Subject: [PATCH] [SERVICES] Starting multiples services concurrently might
crash the system due to concurrent access to the std::list<>.
---
Source/core/Services.cpp | 28 +++++++++++++++++++++-------
1 file changed, 21 insertions(+), 7 deletions(-)
diff --git a/Source/core/Services.cpp b/Source/core/Services.cpp
index 1aed2d0e..e192ffdd 100644
--- a/Source/core/Services.cpp
+++ b/Source/core/Services.cpp
@@ -38,20 +38,28 @@ namespace Core {
void ServiceAdministrator::Register(IServiceMetadata* metadata, IServiceFactory* factory)
{
+ _adminLock.Lock();
+
// Only register a service once !!!
ASSERT(std::find(_services.begin(), _services.end(), ServiceBlock(metadata, factory)) == _services.end());
_services.emplace_back(metadata, factory);
+
+ _adminLock.Unlock();
}
void ServiceAdministrator::Unregister(IServiceMetadata* metadata, IServiceFactory* factory)
{
+ _adminLock.Lock();
+
ServiceList::iterator index = std::find(_services.begin(), _services.end(), ServiceBlock(metadata, factory));
// Only unregister a service once !!!
ASSERT(index != _services.end());
_services.erase(index);
+
+ _adminLock.Unlock();
}
/* static */ ServiceAdministrator& ServiceAdministrator::Instance()
@@ -61,23 +69,29 @@ namespace Core {
void* ServiceAdministrator::Instantiate(const Library& library, const char name[], const uint32_t version, const uint32_t interfaceNumber)
{
- bool found = false;
+ void* result = nullptr;
+
+ _adminLock.Lock();
+
ServiceList::iterator index = _services.begin();
- while ((index != _services.end()) && (found == false)) {
+ while ((index != _services.end()) && (result == nullptr)) {
const char* thisName = index->first->ServiceName().c_str();
- found = ((strcmp(thisName, name) == 0) && ((version == static_cast<uint32_t>(~0)) || (version == ((index->first->Major() << 8) | index->first->Minor()))));
-
- if (found == false) {
+ if ((strcmp(thisName, name) == 0) && ((version == static_cast<uint32_t>(~0)) || (version == ((index->first->Major() << 8) | index->first->Minor())))) {
+ result = index->second->Create(index->first, library, interfaceNumber);
+ }
+ else {
index++;
}
}
- if(found == false){
+ _adminLock.Unlock();
+
+ if(result == nullptr){
TRACE_L1("Missing implementation classname %s in library %s\n", name, library.Name().c_str());
}
- return (found == true ? index->second->Create(index->first, library, interfaceNumber) : nullptr);
+ return (result);
}
void ServiceAdministrator::ReleaseLibrary(Library& reference)
--
2.34.1