diff options
Diffstat (limited to 'base/worker_thread.cpp')
-rw-r--r-- | base/worker_thread.cpp | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/base/worker_thread.cpp b/base/worker_thread.cpp new file mode 100644 index 0000000000..9556fb581d --- /dev/null +++ b/base/worker_thread.cpp @@ -0,0 +1,73 @@ +#include "base/worker_thread.hpp" + +using namespace std; + +namespace base +{ +WorkerThread::WorkerThread() +{ + m_thread = threads::SimpleThread(&WorkerThread::ProcessTasks, this); +} + +WorkerThread::~WorkerThread() +{ + ASSERT(m_checker.CalledOnOriginalThread(), ()); + Shutdown(Exit::SkipPending); + m_thread.join(); +} + +void WorkerThread::ProcessTasks() +{ + unique_lock<mutex> lk(m_mu, defer_lock); + + while (true) + { + Task task; + + { + lk.lock(); + m_cv.wait(lk, [this]() { return m_shutdown || !m_queue.empty(); }); + + if (m_shutdown) + { + switch (m_exit) + { + case Exit::ExecPending: + { + while (!m_queue.empty()) + { + m_queue.front()(); + m_queue.pop(); + } + break; + } + case Exit::SkipPending: break; + } + + break; + } + + CHECK(!m_queue.empty(), ()); + task = move(m_queue.front()); + m_queue.pop(); + lk.unlock(); + } + + task(); + } +} + +void WorkerThread::Shutdown(Exit e) +{ + ASSERT(m_checker.CalledOnOriginalThread(), ()); + + if (m_shutdown) + return; + + CHECK(!m_shutdown, ()); + lock_guard<mutex> lk(m_mu); + m_shutdown = true; + m_exit = e; + m_cv.notify_one(); +} +} // namespace base |