diff --git a/mainapp.cpp b/mainapp.cpp index 6fe0b6d..900403e 100644 --- a/mainapp.cpp +++ b/mainapp.cpp @@ -170,6 +170,8 @@ void do_thread_work(ThreadData *threadData) { logger->logf(LOG_ERR, "Error cleaning auth back-end: %s", ex.what()); } + + threadData->finished = true; } @@ -697,14 +699,36 @@ void MainApp::start() oneInstanceLock.unlock(); + logger->logf(LOG_DEBUG, "Signaling threads to finish."); for(std::shared_ptr &thread : threads) { thread->queueQuit(); } - for(std::shared_ptr &thread : threads) + logger->logf(LOG_DEBUG, "Waiting for threads to finish."); + int count = 0; + bool waitTimeExpired = false; + while(std::any_of(threads.begin(), threads.end(), [](std::shared_ptr t){ return !t->finished; })) + { + if (count++ >= 5000) + { + waitTimeExpired = true; + break; + } + usleep(1000); + } + + if (waitTimeExpired) + { + logger->logf(LOG_WARNING, "(Some) threads failed to terminate. Program will exit uncleanly. If you're using a plugin, it may not be thread-safe."); + } + else { - thread->waitForQuit(); + for(std::shared_ptr &thread : threads) + { + logger->logf(LOG_DEBUG, "Waiting for thread %d to join.", thread->threadnr); + thread->waitForQuit(); + } } saveState(); diff --git a/threaddata.h b/threaddata.h index b84a971..713c905 100644 --- a/threaddata.h +++ b/threaddata.h @@ -68,6 +68,7 @@ public: Settings settingsLocalCopy; // Is updated on reload, within the thread loop. Authentication authentication; bool running = true; + bool finished = false; std::thread thread; int threadnr = 0; int epollfd = 0;