bitz-server  2.0.0
mpmc_blocking_q.h
1 #pragma once
2 
3 //
4 // Copyright(c) 2018 Gabi Melman.
5 // Distributed under the MIT License (http://opensource.org/licenses/MIT)
6 //
7 
8 // async log helper :
9 // multi producer-multi consumer blocking queue
10 // enqueue(..) - will block until room found to put the new message
11 // enqueue_nowait(..) - will return immediatly with false if no room left in the queue
12 // dequeue_for(..) - will block until the queue is not empty or timeout passed
13 
14 #include <condition_variable>
15 #include <mutex>
16 #include <queue>
17 
18 namespace spdlog {
19 namespace details {
20 
21 template<typename T>
23 {
24 public:
25  using item_type = T;
26  explicit mpmc_bounded_queue(size_t max_items)
27  : max_items_(max_items)
28  {
29  }
30 
31  // try to enqueue and block if no room left
32  void enqueue(T &&item)
33  {
34  {
35  std::unique_lock<std::mutex> lock(queue_mutex_);
36  pop_cv_.wait(lock, [this] { return this->q_.size() < this->max_items_; });
37  q_.push(std::move(item));
38  }
39  push_cv_.notify_one();
40  }
41 
42  // try to enqueue and return immdeialty false if no room left
43  bool enqueue_nowait(T &&item)
44  {
45  {
46  std::unique_lock<std::mutex> lock(queue_mutex_);
47  if (q_.size() == this->max_items_)
48  {
49  return false;
50  }
51  q_.push(std::forward<T>(item));
52  }
53  push_cv_.notify_one();
54  return true;
55  }
56 
57  // try to dequeue item. if no item found. wait upto timeout and try again
58  // Return true, if succeeded dequeue item, false otherwise
59  bool dequeue_for(T &popped_item, std::chrono::milliseconds wait_duration)
60  {
61  {
62  std::unique_lock<std::mutex> lock(queue_mutex_);
63  if (!push_cv_.wait_for(lock, wait_duration, [this] { return this->q_.size() > 0; }))
64  {
65  return false;
66  }
67 
68  popped_item = std::move(q_.front());
69  q_.pop();
70  }
71  pop_cv_.notify_one();
72  return true;
73  }
74 
75 private:
76  size_t max_items_;
77  std::mutex queue_mutex_;
78  std::condition_variable push_cv_;
79  std::condition_variable pop_cv_;
80 
81  std::queue<T> q_;
82 };
83 } // namespace details
84 } // namespace spdlog
Definition: async_logger.h:26
Definition: mpmc_blocking_q.h:22