Fixed bug where after a while std::thread throws an uncaught exception.

This commit is contained in:
hg
2014-06-20 10:21:53 +02:00
parent 116947ef03
commit 40d5753edc
2 changed files with 43 additions and 6 deletions
+37 -5
View File
@@ -35,15 +35,29 @@ void IPCManager::listenerThreadFunc(IPCManager* obj) {
perror("Error while trying to accept incoming connection"); perror("Error while trying to accept incoming connection");
logger << log4cpp::Priority::ERROR << "Error while trying to accept incoming connection"; logger << log4cpp::Priority::ERROR << "Error while trying to accept incoming connection";
} else { } else {
logger << log4cpp::Priority::INFO << "Successfully accepted new ipc connection."; std::lock_guard<std::mutex> 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 // Now we create a new thread that handles the established connection
std::thread* handleThread = new std::thread(workerThreadFunc, obj, cSocketFD, handleThread); try {
obj->workerThreads.insert(handleThread); 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 // To something
bool loopFlag = true; bool loopFlag = true;
while (loopFlag) { while (loopFlag) {
@@ -106,7 +120,25 @@ void IPCManager::workerThreadFunc(IPCManager* obj, int socket, std::thread* self
} }
// Cleanup resources // Cleanup resources
close(socket); close(socket);
obj->workerThreads.erase(self); obj->signalWorkerThreadEnd(std::this_thread::get_id());
}
void IPCManager::signalWorkerThreadEnd(std::thread::id thrid) {
std::lock_guard<std::mutex> 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.";
}
} }
+6 -1
View File
@@ -11,6 +11,7 @@
#include <string> #include <string>
#include <thread> #include <thread>
#include <set> #include <set>
#include <mutex>
#include <log4cpp/Category.hh> #include <log4cpp/Category.hh>
namespace growcontrol { namespace growcontrol {
@@ -23,13 +24,17 @@ private:
GrowControl* growControl = nullptr; GrowControl* growControl = nullptr;
std::mutex ipcMutex;
std::string socketPath; std::string socketPath;
int socketFD = -1; int socketFD = -1;
std::thread* listenerThread = nullptr; std::thread* listenerThread = nullptr;
bool listenerThreadFlag = false; bool listenerThreadFlag = false;
std::set<std::thread*> workerThreads; std::set<std::thread*> workerThreads;
std::set<std::thread*> toBeDeletedThreads;
bool configFlag = false; bool configFlag = false;
void signalWorkerThreadEnd(std::thread::id thrid);
public: public:
IPCManager(); IPCManager();
virtual ~IPCManager(); virtual ~IPCManager();
@@ -40,7 +45,7 @@ public:
static void listenerThreadFunc(IPCManager* obj); 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<std::string> args); std::string handleGetValCommand(std::vector<std::string> args);
std::string handleSetValCommand(std::string obj, std::string value); std::string handleSetValCommand(std::string obj, std::string value);