Skip to content

Commit

Permalink
#5345: Add TaskQueue which sequentially executes the queued tasks usi…
Browse files Browse the repository at this point in the history
…ng std::async.
  • Loading branch information
codereader committed Oct 3, 2020
1 parent 332f51f commit 4ceae9e
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 0 deletions.
84 changes: 84 additions & 0 deletions libs/TaskQueue.h
@@ -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();
});
}
};

}
1 change: 1 addition & 0 deletions tools/msvc/libs.vcxproj
Expand Up @@ -235,6 +235,7 @@
<ClInclude Include="..\..\libs\string\tokeniser.h" />
<ClInclude Include="..\..\libs\string\trim.h" />
<ClInclude Include="..\..\libs\SurfaceShader.h" />
<ClInclude Include="..\..\libs\TaskQueue.h" />
<ClInclude Include="..\..\libs\texturelib.h" />
<ClInclude Include="..\..\libs\ThreadedDefLoader.h" />
<ClInclude Include="..\..\libs\time\ScopeTimer.h" />
Expand Down
1 change: 1 addition & 0 deletions tools/msvc/libs.vcxproj.filters
Expand Up @@ -261,6 +261,7 @@
<ClInclude Include="..\..\libs\selection\SelectionVolume.h">
<Filter>selection</Filter>
</ClInclude>
<ClInclude Include="..\..\libs\TaskQueue.h" />
</ItemGroup>
<ItemGroup>
<Filter Include="util">
Expand Down

0 comments on commit 4ceae9e

Please sign in to comment.