diff --git a/src/IPCManager.cpp b/src/IPCManager.cpp index 8984925..1dafbe1 100644 --- a/src/IPCManager.cpp +++ b/src/IPCManager.cpp @@ -35,15 +35,29 @@ void IPCManager::listenerThreadFunc(IPCManager* obj) { perror("Error while trying to accept incoming connection"); logger << log4cpp::Priority::ERROR << "Error while trying to accept incoming connection"; } else { - logger << log4cpp::Priority::INFO << "Successfully accepted new ipc connection."; + std::lock_guard lock(obj->ipcMutex); + logger << log4cpp::Priority::DEBUG << "Successfully accepted new ipc connection."; + // Delete old threads + if (obj->toBeDeletedThreads.size() > 0) { + for (auto t : obj->toBeDeletedThreads) { + t->join(); + delete t; + } + obj->toBeDeletedThreads.clear(); + } // Now we create a new thread that handles the established connection - std::thread* handleThread = new std::thread(workerThreadFunc, obj, cSocketFD, handleThread); - obj->workerThreads.insert(handleThread); + try { + std::thread* handleThread = new std::thread(workerThreadFunc, obj, cSocketFD); + obj->workerThreads.insert(handleThread); + } catch (std::exception &e) { + logger << log4cpp::Priority::ERROR << "Could not start ipc worker thread: " << e.what(); + close(cSocketFD); + } } } } -void IPCManager::workerThreadFunc(IPCManager* obj, int socket, std::thread* self) { +void IPCManager::workerThreadFunc(IPCManager* obj, int socket) { // To something bool loopFlag = true; while (loopFlag) { @@ -106,7 +120,25 @@ void IPCManager::workerThreadFunc(IPCManager* obj, int socket, std::thread* self } // Cleanup resources close(socket); - obj->workerThreads.erase(self); + obj->signalWorkerThreadEnd(std::this_thread::get_id()); +} + + +void IPCManager::signalWorkerThreadEnd(std::thread::id thrid) { + std::lock_guard lock(ipcMutex); + std::thread* foundThread = nullptr; + for (auto t : workerThreads) { + if (t->get_id() == thrid) { + foundThread = t; + break; + } + } + if (foundThread != nullptr) { + workerThreads.erase(foundThread); + toBeDeletedThreads.insert(foundThread); + } else { + logger << log4cpp::Priority::ERROR << "Error IPCManager::signalThreadEnd: Could not find thread."; + } } diff --git a/src/IPCManager.h b/src/IPCManager.h index 3a5d405..1f6643b 100644 --- a/src/IPCManager.h +++ b/src/IPCManager.h @@ -11,6 +11,7 @@ #include #include #include +#include #include namespace growcontrol { @@ -23,13 +24,17 @@ private: GrowControl* growControl = nullptr; + std::mutex ipcMutex; std::string socketPath; int socketFD = -1; std::thread* listenerThread = nullptr; bool listenerThreadFlag = false; std::set workerThreads; + std::set toBeDeletedThreads; bool configFlag = false; + void signalWorkerThreadEnd(std::thread::id thrid); + public: IPCManager(); virtual ~IPCManager(); @@ -40,7 +45,7 @@ public: static void listenerThreadFunc(IPCManager* obj); - static void workerThreadFunc(IPCManager* obj, int socket, std::thread* self); + static void workerThreadFunc(IPCManager* obj, int socket); std::string handleGetValCommand(std::vector args); std::string handleSetValCommand(std::string obj, std::string value);