Skip to content

Commit

Permalink
fix deadlock in scoped_timer destructor (#5371)
Browse files Browse the repository at this point in the history
  • Loading branch information
zhouzhenghui authored Dec 21, 2021
1 parent 94a2c91 commit 9d82c1d
Showing 1 changed file with 12 additions and 8 deletions.
20 changes: 12 additions & 8 deletions src/util/scoped_timer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,14 @@ Revision History:
#include <pthread.h>
#endif

enum scoped_timer_work_state { IDLE = 0, WORKING = 1, EXITING = 2 };

struct scoped_timer_state {
std::thread m_thread;
std::timed_mutex m_mutex;
event_handler * eh;
unsigned ms;
std::atomic<int> work;
std::atomic<scoped_timer_work_state> work;
std::condition_variable_any cv;
};

Expand All @@ -49,11 +51,11 @@ static atomic<unsigned> num_workers(0);
static void thread_func(scoped_timer_state *s) {
workers.lock();
while (true) {
s->cv.wait(workers, [=]{ return s->work > 0; });
s->cv.wait(workers, [=]{ return s->work > IDLE; });
workers.unlock();

// exiting..
if (s->work == 2)
if (s->work == EXITING)
return;

auto end = std::chrono::steady_clock::now() + std::chrono::milliseconds(s->ms);
Expand All @@ -68,9 +70,8 @@ static void thread_func(scoped_timer_state *s) {
s->m_mutex.unlock();

next:
s->work = 0;
s->work = IDLE;
workers.lock();
available_workers.push_back(s);
}
}

Expand All @@ -97,7 +98,7 @@ struct scoped_timer::imp {
s->ms = ms;
s->eh = eh;
s->m_mutex.lock();
s->work = 1;
s->work = WORKING;
if (new_worker) {
s->m_thread = std::thread(thread_func, s);
}
Expand All @@ -108,8 +109,11 @@ struct scoped_timer::imp {

~imp() {
s->m_mutex.unlock();
while (s->work == 1)
while (s->work == WORKING)
std::this_thread::yield();
workers.lock();
available_workers.push_back(s);
workers.unlock();
}
};

Expand Down Expand Up @@ -139,7 +143,7 @@ void scoped_timer::finalize() {
while (deleted < num_workers) {
workers.lock();
for (auto w : available_workers) {
w->work = 2;
w->work = EXITING;
w->cv.notify_one();
}
decltype(available_workers) cleanup_workers;
Expand Down

0 comments on commit 9d82c1d

Please sign in to comment.