From 8111b77e95b083137faf888aeb5892073adf7ab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Wed, 27 Jun 2018 16:59:37 +0200 Subject: New upstream version 2.0.0 --- lib/spdlog/details/mpmc_blocking_q.h | 84 ++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 lib/spdlog/details/mpmc_blocking_q.h (limited to 'lib/spdlog/details/mpmc_blocking_q.h') diff --git a/lib/spdlog/details/mpmc_blocking_q.h b/lib/spdlog/details/mpmc_blocking_q.h new file mode 100644 index 0000000..d4a8a41 --- /dev/null +++ b/lib/spdlog/details/mpmc_blocking_q.h @@ -0,0 +1,84 @@ +#pragma once + +// +// Copyright(c) 2018 Gabi Melman. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) +// + +// async log helper : +// multi producer-multi consumer blocking queue +// enqueue(..) - will block until room found to put the new message +// enqueue_nowait(..) - will return immediatly with false if no room left in the queue +// dequeue_for(..) - will block until the queue is not empty or timeout passed + +#include +#include +#include + +namespace spdlog { +namespace details { + +template +class mpmc_bounded_queue +{ +public: + using item_type = T; + explicit mpmc_bounded_queue(size_t max_items) + : max_items_(max_items) + { + } + + // try to enqueue and block if no room left + void enqueue(T &&item) + { + { + std::unique_lock lock(queue_mutex_); + pop_cv_.wait(lock, [this] { return this->q_.size() < this->max_items_; }); + q_.push(std::move(item)); + } + push_cv_.notify_one(); + } + + // try to enqueue and return immdeialty false if no room left + bool enqueue_nowait(T &&item) + { + { + std::unique_lock lock(queue_mutex_); + if (q_.size() == this->max_items_) + { + return false; + } + q_.push(std::forward(item)); + } + push_cv_.notify_one(); + return true; + } + + // try to dequeue item. if no item found. wait upto timeout and try again + // Return true, if succeeded dequeue item, false otherwise + bool dequeue_for(T &popped_item, std::chrono::milliseconds wait_duration) + { + { + std::unique_lock lock(queue_mutex_); + if (!push_cv_.wait_for(lock, wait_duration, [this] { return this->q_.size() > 0; })) + { + return false; + } + + popped_item = std::move(q_.front()); + q_.pop(); + } + pop_cv_.notify_one(); + return true; + } + +private: + size_t max_items_; + std::mutex queue_mutex_; + std::condition_variable push_cv_; + std::condition_variable pop_cv_; + + std::queue q_; +}; +} // namespace details +} // namespace spdlog -- cgit v1.2.3