reapack

Package manager for REAPER
Log | Files | Refs | Submodules | README | LICENSE

commit 010c13e381ae264918bde2e4056c83cddcaa0534
parent 298b5b6a0744f982f45acaa3095040330408ce6e
Author: cfillion <cfillion@users.noreply.github.com>
Date:   Mon, 24 Sep 2018 23:11:28 -0400

modify the thread stop shared variable while the mutex is locked

https://stackoverflow.com/a/36130475/796375

Diffstat:
Msrc/thread.cpp | 28++++++++++++++++++++--------
Msrc/thread.hpp | 3+--
2 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/src/thread.cpp b/src/thread.cpp @@ -88,26 +88,38 @@ void ThreadTask::exec() ThreadNotifier::get()->notify({this, state}); }; -WorkerThread::WorkerThread() : m_exit(false), m_thread(&WorkerThread::run, this) +WorkerThread::WorkerThread() : m_stop(false), m_thread(&WorkerThread::run, this) { } WorkerThread::~WorkerThread() { - m_exit = true; + { + std::lock_guard lock(m_mutex); + m_stop = true; + } + m_wake.notify_one(); m_thread.join(); } void WorkerThread::run() { - do { - while(ThreadTask *task = nextTask()) - task->exec(); + unique_lock<mutex> lock(m_mutex); + + while(true) { + m_wake.wait(lock, [=] { return !m_queue.empty() || m_stop; }); + + if(m_stop) + break; - unique_lock<mutex> lock(m_mutex); - m_wake.wait(lock); - } while(!m_exit); + ThreadTask *task = m_queue.front(); + m_queue.pop(); + + lock.unlock(); + task->exec(); + lock.lock(); + } #ifdef _WIN32 // HACK: Destruct thread-local storage objects earlier on Windows to avoid a diff --git a/src/thread.hpp b/src/thread.hpp @@ -21,7 +21,6 @@ #include "errors.hpp" #include <array> -#include <atomic> #include <condition_variable> #include <functional> #include <queue> @@ -89,8 +88,8 @@ private: void run(); ThreadTask *nextTask(); + bool m_stop; std::mutex m_mutex; - std::atomic_bool m_exit; std::condition_variable m_wake; std::queue<ThreadTask *> m_queue;