Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#5345: Add TaskQueue which sequentially executes the queued tasks usi…
…ng std::async.
- Loading branch information
1 parent
332f51f
commit 4ceae9e
Showing
3 changed files
with
86 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
#pragma once | ||
|
||
#include <mutex> | ||
#include <list> | ||
#include <functional> | ||
#include <future> | ||
|
||
namespace util | ||
{ | ||
|
||
class TaskQueue | ||
{ | ||
private: | ||
std::mutex _lock; | ||
|
||
std::list<std::function<void()>> _queue; | ||
|
||
std::future<void> _current; | ||
|
||
public: | ||
~TaskQueue() | ||
{ | ||
clear(); | ||
} | ||
|
||
// Adds the given task to the queue. This will launch the task | ||
// immediately if no other task is currently processed | ||
void enqueue(const std::function<void()>& task) | ||
{ | ||
{ | ||
std::lock_guard<std::mutex> lock(_lock); | ||
_queue.push_front(task); | ||
} | ||
|
||
if (isIdle()) | ||
{ | ||
startNextTask(); | ||
} | ||
} | ||
|
||
// Clears the queue. This might block waiting for any currently | ||
// active taks to finish | ||
void clear() | ||
{ | ||
{ | ||
// Lock the queue and remove any tasks such that no new ones are added | ||
std::lock_guard<std::mutex> lock(_lock); | ||
_queue.clear(); | ||
} | ||
|
||
// Clear (and possibly) wait for the currently active future object | ||
_current = std::future<void>(); | ||
} | ||
|
||
private: | ||
bool isIdle() const | ||
{ | ||
return !_current.valid() || | ||
_current.wait_for(std::chrono::seconds(0)) == std::future_status::ready; | ||
} | ||
|
||
void startNextTask() | ||
{ | ||
std::lock_guard<std::mutex> lock(_lock); | ||
|
||
if (_queue.empty()) | ||
{ | ||
return; | ||
} | ||
|
||
// No active task, dispatch a new one | ||
auto frontOfQueue = _queue.front(); | ||
_queue.pop_front(); | ||
|
||
// Wrap the given task in our own lambda to start the next task right afterwards | ||
_current = std::async(std::launch::async, [this, frontOfQueue]() | ||
{ | ||
frontOfQueue(); | ||
startNextTask(); | ||
}); | ||
} | ||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters