From de0701fa0964ccc8f499d288a7d35a65043eb034 Mon Sep 17 00:00:00 2001 From: Yuri Gorshenin Date: Wed, 28 Jun 2017 13:13:07 +0300 Subject: [base] Fixed possible deadlock on WorkerThread shutdown. --- base/base_tests/worker_thread_tests.cpp | 19 +++++++++++++++++++ base/worker_thread.cpp | 5 +---- 2 files changed, 20 insertions(+), 4 deletions(-) (limited to 'base') diff --git a/base/base_tests/worker_thread_tests.cpp b/base/base_tests/worker_thread_tests.cpp index be601e1540..309112bf00 100644 --- a/base/base_tests/worker_thread_tests.cpp +++ b/base/base_tests/worker_thread_tests.cpp @@ -3,6 +3,7 @@ #include "base/worker_thread.hpp" #include +#include #include using namespace base; @@ -67,4 +68,22 @@ UNIT_TEST(WorkerThread_SimpleFlush) } TEST_EQUAL(value, 1024, ()); } + +UNIT_TEST(WorkerThread_PushFromPendingTask) +{ + // promise - future pair is used as a socketpair here to pass a + // signal from the main thread to the worker thread. + promise p; + auto f = p.get_future(); + + WorkerThread thread; + bool const rv = thread.Push([&]() { + f.get(); + bool const rv = thread.Push([&]() { TEST(false, ("This task should not be executed")); }); + TEST(!rv, ()); + }); + TEST(rv, ()); + thread.Shutdown(WorkerThread::Exit::ExecPending); + p.set_value(); +} } // namespace diff --git a/base/worker_thread.cpp b/base/worker_thread.cpp index f0dc9af050..dffbdc2ee2 100644 --- a/base/worker_thread.cpp +++ b/base/worker_thread.cpp @@ -20,14 +20,12 @@ void WorkerThread::ProcessTasks() { queue pending; - unique_lock lk(m_mu, defer_lock); - while (true) { Task task; { - lk.lock(); + unique_lock lk(m_mu); m_cv.wait(lk, [this]() { return m_shutdown || !m_queue.empty(); }); if (m_shutdown) @@ -46,7 +44,6 @@ void WorkerThread::ProcessTasks() CHECK(!m_queue.empty(), ()); task = move(m_queue.front()); m_queue.pop(); - lk.unlock(); } task(); -- cgit v1.2.3