Commit 7a90acf8699f11cd1c4844c64e710e7522f20dd6

Authored by Wiebe Cazemier
1 parent 477dd009

Add finish timeout on threads on exit

Showing 2 changed files with 27 additions and 2 deletions
mainapp.cpp
@@ -170,6 +170,8 @@ void do_thread_work(ThreadData *threadData) @@ -170,6 +170,8 @@ void do_thread_work(ThreadData *threadData)
170 { 170 {
171 logger->logf(LOG_ERR, "Error cleaning auth back-end: %s", ex.what()); 171 logger->logf(LOG_ERR, "Error cleaning auth back-end: %s", ex.what());
172 } 172 }
  173 +
  174 + threadData->finished = true;
173 } 175 }
174 176
175 177
@@ -697,14 +699,36 @@ void MainApp::start() @@ -697,14 +699,36 @@ void MainApp::start()
697 699
698 oneInstanceLock.unlock(); 700 oneInstanceLock.unlock();
699 701
  702 + logger->logf(LOG_DEBUG, "Signaling threads to finish.");
700 for(std::shared_ptr<ThreadData> &thread : threads) 703 for(std::shared_ptr<ThreadData> &thread : threads)
701 { 704 {
702 thread->queueQuit(); 705 thread->queueQuit();
703 } 706 }
704 707
705 - for(std::shared_ptr<ThreadData> &thread : threads) 708 + logger->logf(LOG_DEBUG, "Waiting for threads to finish.");
  709 + int count = 0;
  710 + bool waitTimeExpired = false;
  711 + while(std::any_of(threads.begin(), threads.end(), [](std::shared_ptr<ThreadData> t){ return !t->finished; }))
  712 + {
  713 + if (count++ >= 5000)
  714 + {
  715 + waitTimeExpired = true;
  716 + break;
  717 + }
  718 + usleep(1000);
  719 + }
  720 +
  721 + if (waitTimeExpired)
  722 + {
  723 + 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.");
  724 + }
  725 + else
706 { 726 {
707 - thread->waitForQuit(); 727 + for(std::shared_ptr<ThreadData> &thread : threads)
  728 + {
  729 + logger->logf(LOG_DEBUG, "Waiting for thread %d to join.", thread->threadnr);
  730 + thread->waitForQuit();
  731 + }
708 } 732 }
709 733
710 saveState(); 734 saveState();
threaddata.h
@@ -68,6 +68,7 @@ public: @@ -68,6 +68,7 @@ public:
68 Settings settingsLocalCopy; // Is updated on reload, within the thread loop. 68 Settings settingsLocalCopy; // Is updated on reload, within the thread loop.
69 Authentication authentication; 69 Authentication authentication;
70 bool running = true; 70 bool running = true;
  71 + bool finished = false;
71 std::thread thread; 72 std::thread thread;
72 int threadnr = 0; 73 int threadnr = 0;
73 int epollfd = 0; 74 int epollfd = 0;