mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-22 05:04:30 +02:00
Fix deadlock in ThreadPool::Stop
This commit is contained in:
parent
02fef3f84a
commit
f20d9010c0
@ -321,8 +321,6 @@ mainloop:
|
|||||||
GetTP().Stop();
|
GetTP().Stop();
|
||||||
m_ShuttingDown = false;
|
m_ShuttingDown = false;
|
||||||
|
|
||||||
GetTP().Join(true);
|
|
||||||
|
|
||||||
Timer::Uninitialize();
|
Timer::Uninitialize();
|
||||||
#endif /* _DEBUG */
|
#endif /* _DEBUG */
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,6 @@ ThreadPool::ThreadPool(size_t max_threads)
|
|||||||
ThreadPool::~ThreadPool(void)
|
ThreadPool::~ThreadPool(void)
|
||||||
{
|
{
|
||||||
Stop();
|
Stop();
|
||||||
Join(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadPool::Start(void)
|
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++)
|
for (size_t i = 0; i < sizeof(m_Queues) / sizeof(m_Queues[0]); i++)
|
||||||
m_Queues[i].SpawnWorker(m_ThreadGroup);
|
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)
|
void ThreadPool::Stop(void)
|
||||||
{
|
{
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(m_MgmtMutex);
|
||||||
|
m_Stopped = true;
|
||||||
|
m_MgmtCV.notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_MgmtThread.join();
|
||||||
|
|
||||||
for (size_t i = 0; i < sizeof(m_Queues) / sizeof(m_Queues[0]); i++) {
|
for (size_t i = 0; i < sizeof(m_Queues) / sizeof(m_Queues[0]); i++) {
|
||||||
boost::mutex::scoped_lock lock(m_Queues[i].Mutex);
|
boost::mutex::scoped_lock lock(m_Queues[i].Mutex);
|
||||||
m_Queues[i].Stopped = true;
|
m_Queues[i].Stopped = true;
|
||||||
m_Queues[i].CV.notify_all();
|
m_Queues[i].CV.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();
|
m_ThreadGroup.join_all();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,7 +53,6 @@ public:
|
|||||||
|
|
||||||
void Start(void);
|
void Start(void);
|
||||||
void Stop(void);
|
void Stop(void);
|
||||||
void Join(bool wait_for_stop = false);
|
|
||||||
|
|
||||||
bool Post(const WorkFunction& callback, SchedulerPolicy policy = DefaultScheduler);
|
bool Post(const WorkFunction& callback, SchedulerPolicy policy = DefaultScheduler);
|
||||||
|
|
||||||
@ -122,6 +121,7 @@ private:
|
|||||||
|
|
||||||
boost::thread_group m_ThreadGroup;
|
boost::thread_group m_ThreadGroup;
|
||||||
|
|
||||||
|
boost::thread m_MgmtThread;
|
||||||
boost::mutex m_MgmtMutex;
|
boost::mutex m_MgmtMutex;
|
||||||
boost::condition_variable m_MgmtCV;
|
boost::condition_variable m_MgmtCV;
|
||||||
bool m_Stopped;
|
bool m_Stopped;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user