]> granicus.if.org Git - icinga2/commitdiff
Fix deadlock in ThreadPool::Stop
authorGunnar Beutner <gunnar.beutner@netways.de>
Thu, 13 Nov 2014 09:00:49 +0000 (10:00 +0100)
committerGunnar Beutner <gunnar.beutner@netways.de>
Thu, 13 Nov 2014 09:00:49 +0000 (10:00 +0100)
lib/base/application.cpp
lib/base/threadpool.cpp
lib/base/threadpool.hpp

index 204ca752d1e34185ff1fae21a2dc9b8a354bc37f..d5085bfd775c550fa008ac19f4dee510c3667019 100644 (file)
@@ -321,8 +321,6 @@ mainloop:
        GetTP().Stop();
        m_ShuttingDown = false;
 
-       GetTP().Join(true);
-
        Timer::Uninitialize();
 #endif /* _DEBUG */
 }
index d35bf69f48afb3ebc6162bec88d8db8c49c6bb6d..3ffae3a93eee916bb86a54b8c27f03873eeff2b0 100644 (file)
@@ -41,7 +41,6 @@ ThreadPool::ThreadPool(size_t max_threads)
 ThreadPool::~ThreadPool(void)
 {
        Stop();
-       Join(true);
 }
 
 void ThreadPool::Start(void)
@@ -49,38 +48,26 @@ void ThreadPool::Start(void)
        for (size_t i = 0; i < sizeof(m_Queues) / sizeof(m_Queues[0]); i++)
                m_Queues[i].SpawnWorker(m_ThreadGroup);
 
-       m_ThreadGroup.create_thread(boost::bind(&ThreadPool::ManagerThreadProc, this));
+       m_MgmtThread = boost::move(boost::thread(boost::bind(&ThreadPool::ManagerThreadProc, this)));
 }
 
 void ThreadPool::Stop(void)
 {
-       for (size_t i = 0; i < sizeof(m_Queues) / sizeof(m_Queues[0]); i++) {
-               boost::mutex::scoped_lock lock(m_Queues[i].Mutex);
-               m_Queues[i].Stopped = true;
-               m_Queues[i].CV.notify_all();
+       {
+               boost::mutex::scoped_lock lock(m_MgmtMutex);
+               m_Stopped = true;
+               m_MgmtCV.notify_all();
        }
 
-       boost::mutex::scoped_lock lock(m_MgmtMutex);
-       m_Stopped = true;
-       m_MgmtCV.notify_all();
-}
-
-/**
- * Waits for all worker threads to finish.
- */
-void ThreadPool::Join(bool wait_for_stop)
-{
-       if (wait_for_stop) {
-               m_ThreadGroup.join_all();
-               return;
-       }
+       m_MgmtThread.join();
 
        for (size_t i = 0; i < sizeof(m_Queues) / sizeof(m_Queues[0]); i++) {
                boost::mutex::scoped_lock lock(m_Queues[i].Mutex);
-
-               while (!m_Queues[i].Items.empty())
-                       m_Queues[i].CVStarved.wait(lock);
+               m_Queues[i].Stopped = true;
+               m_Queues[i].CV.notify_all();
        }
+
+       m_ThreadGroup.join_all();
 }
 
 /**
index c34fd80a8c68ce7660c552e2729e1b907082f087..afae6c0b840d6c434588f221bddac52140eacb69 100644 (file)
@@ -53,7 +53,6 @@ public:
 
        void Start(void);
        void Stop(void);
-       void Join(bool wait_for_stop = false);
 
        bool Post(const WorkFunction& callback, SchedulerPolicy policy = DefaultScheduler);
 
@@ -122,6 +121,7 @@ private:
 
        boost::thread_group m_ThreadGroup;
 
+       boost::thread m_MgmtThread;
        boost::mutex m_MgmtMutex;
        boost::condition_variable m_MgmtCV;
        bool m_Stopped;