Skip to content

Instantly share code, notes, and snippets.

@Journeyman1337
Last active September 30, 2021 20:39
Show Gist options
  • Save Journeyman1337/006c5c94b67e2b15b0c6bdfadf53f435 to your computer and use it in GitHub Desktop.
Save Journeyman1337/006c5c94b67e2b15b0c6bdfadf53f435 to your computer and use it in GitHub Desktop.
concept of a concurrent queue in cpp
#pragma once
#include <mutex>
#include <queue>
#include <optional>
namespace prpg
{
template <class T>
class ConcurrentQueue
{
private:
std::queue<T> in;
std::mutex in_mutex;
std::queue<T> out;
std::mutex out_mutex;
std::atomic<bool> swap_ready = false;
public:
ConcurrentQueue() = default;
ConcurrentQueue(const ConcurrentQueue& other) = delete;
ConcurrentQueue(ConcurrentQueue&& other) = delete;
ConcurrentQueue& operator=(const ConcurrentQueue& other) = delete;
ConcurrentQueue& operator=(ConcurrentQueue&& other) = delete;
~ConcurrentQueue() = default;
void push(const T& item)
{
std::unique_lock<std::mutex> in_lock(in_mutex);
in.push(item);
}
std::optional<T> pop()
{
std::unique_lock<std::mutex> out_lock(out_mutex);
this->swap_ready = (out.size() == 1);
return out.pop();
}
bool try_swap()
{
if (!this->swap_ready)
{
return false;
}
std::unique_lock<std::mutex> in_lock(in_mutex, std::defer_lock);
std::unique_lock<std::mutex> out_lock(out_mutex, std::defer_lock);
if (std::try_lock(in_lock, out_lock))
{
in.swap(out);
return true;
}
return false;
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment