Skip to content

Instantly share code, notes, and snippets.

@mark-boer
Last active April 28, 2021 13:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mark-boer/a75f4f15525acf6577d65a3405585044 to your computer and use it in GitHub Desktop.
Save mark-boer/a75f4f15525acf6577d65a3405585044 to your computer and use it in GitHub Desktop.
#include <mutex>
#include <queue>
#include <condition_variable>
#include <optional>
#include <chrono>
template<typename T>
class SynchronisationQueue {
public:
void put(const T& val)
{
std::lock_guard<std::mutex> lck(mtx_);
queue_.push(val);
cv_.notify_one();
}
void put(T&& val)
{
std::lock_guard<std::mutex> lck(mtx_);
queue_.push(std::move(val));
cv_.notify_one();
}
T get() {
std::unique_lock<std::mutex> lck(mtx_);
while (queue_.empty())
cv_.wait(lck);
T ret_val = queue_.front();
queue_.pop();
return ret_val;
}
std::optional<T> get_nowait() {
std::lock_guard<std::mutex> lck(mtx_);
if (queue_.empty())
return std::nullopt;
T ret_val = queue_.front();
queue_.pop();
return ret_val;
}
template <typename R, typename P>
std::optional<T> get(std::chrono::duration<R, P> timeout) {
auto end_time = std::chrono::steady_clock::now() + timeout;
std::unique_lock<std::mutex> lck(mtx_);
while (queue_.empty())
if (cv_.wait_until(lck, end_time) == std::cv_status::timeout) {
return std::nullopt;
}
T ret_val = queue_.front();
queue_.pop();
return ret_val;
}
size_t size() const
{
std::lock_guard<std::mutex> lck(mtx_);
return queue_.size();
}
void clear()
{
std::lock_guard<std::mutex> lck(mtx_);
queue_ = std::queue<T>();
}
private:
std::mutex mtx_;
std::queue<T> queue_;
std::condition_variable cv_;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment