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:
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;