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 170 {
171 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 699  
698 700 oneInstanceLock.unlock();
699 701  
  702 + logger->logf(LOG_DEBUG, "Signaling threads to finish.");
700 703 for(std::shared_ptr<ThreadData> &thread : threads)
701 704 {
702 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 734 saveState();
... ...
threaddata.h
... ... @@ -68,6 +68,7 @@ public:
68 68 Settings settingsLocalCopy; // Is updated on reload, within the thread loop.
69 69 Authentication authentication;
70 70 bool running = true;
  71 + bool finished = false;
71 72 std::thread thread;
72 73 int threadnr = 0;
73 74 int epollfd = 0;
... ...