diff --git a/Concurrency/AsyncTaskQueue.cpp b/Concurrency/AsyncTaskQueue.cpp index 6f9f40027..75ae57175 100644 --- a/Concurrency/AsyncTaskQueue.cpp +++ b/Concurrency/AsyncTaskQueue.cpp @@ -17,23 +17,25 @@ AsyncTaskQueue::AsyncTaskQueue() : should_destruct_(false) { std::function next_function; - queue_mutex_.lock(); + // Take lock, check for a new task + std::unique_lock lock(queue_mutex_); if(!pending_tasks_.empty()) { next_function = pending_tasks_.front(); pending_tasks_.pop_front(); } - queue_mutex_.unlock(); if(next_function) { + // If there is a task, release lock and perform it + lock.unlock(); next_function(); } else { - std::unique_lock lock(queue_mutex_); + // If there isn't a task, atomically block on the processing condition and release the lock + // until there's something pending (and then release it again via scope) processing_condition_.wait(lock); - lock.unlock(); } } })); @@ -44,15 +46,13 @@ AsyncTaskQueue::~AsyncTaskQueue() should_destruct_ = true; enqueue([](){}); thread_->join(); + thread_.reset( ); } void AsyncTaskQueue::enqueue(std::function function) { - queue_mutex_.lock(); - pending_tasks_.push_back(function); - queue_mutex_.unlock(); - std::lock_guard lock(queue_mutex_); + pending_tasks_.push_back(function); processing_condition_.notify_all(); }