diff options
author | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2018-06-27 16:59:39 +0200 |
---|---|---|
committer | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2018-06-27 16:59:39 +0200 |
commit | f1187001ebc5b9ad18d5b5992c75bd682e367b42 (patch) | |
tree | 134ca05c369ac09dd7fa5f51285cc7176d62c385 /lib/spdlog/details/mpmc_blocking_q.h | |
parent | b84c8622d092fd773888eed89f1dbffb2c3a57f7 (diff) | |
parent | 8111b77e95b083137faf888aeb5892073adf7ab4 (diff) |
Update upstream source from tag 'upstream/2.0.0'
Update to upstream version '2.0.0'
with Debian dir 112f2f2cb91158baaf8ee3a1f623980b43a258ce
Diffstat (limited to 'lib/spdlog/details/mpmc_blocking_q.h')
-rw-r--r-- | lib/spdlog/details/mpmc_blocking_q.h | 84 |
1 files changed, 84 insertions, 0 deletions
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 <condition_variable> +#include <mutex> +#include <queue> + +namespace spdlog { +namespace details { + +template<typename T> +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<std::mutex> 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<std::mutex> lock(queue_mutex_); + if (q_.size() == this->max_items_) + { + return false; + } + q_.push(std::forward<T>(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<std::mutex> 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<T> q_; +}; +} // namespace details +} // namespace spdlog |