ArrayBlockingQueue.hpp
Go to the documentation of this file.
1 // @formatter:off
2 //
3 // Balau core C++ library
4 //
5 // Copyright (C) 2008 Bora Software (contact@borasoftware.com)
6 //
7 // Licensed under the Boost Software License - Version 1.0 - August 17th, 2003.
8 // See the LICENSE file for the full license text.
9 //
10 
16 
17 #ifndef COM_BORA_SOFTWARE__BALAU_CONTAINER__ARRAY_BLOCKING_QUEUE
18 #define COM_BORA_SOFTWARE__BALAU_CONTAINER__ARRAY_BLOCKING_QUEUE
19 
21 #include <Balau/Type/StdTypes.hpp>
22 
23 #include <condition_variable>
24 
25 namespace Balau::Container {
26 
35 template <typename T> class ArrayBlockingQueue : public BlockingQueue<T> {
39  public: explicit ArrayBlockingQueue(unsigned int capacity)
40  : elements(capacity)
41  , count(0)
42  , head(0)
43  , tail(0) {}
44 
45  public: void enqueue(T && element) override {
46  std::unique_lock<std::mutex> lock(mutex);
47 
48  while (full()) {
49  enqueueCondition.wait(lock);
50  }
51 
52  elements[head] = std::move(element);
53  increment(head);
54  ++count;
55 
56  // When two threads are dequeueing, the second thread could
57  // miss the notify call if it is outside of the lock.
58  dequeueCondition.notify_one();
59  }
60 
61  public: T dequeue() override {
62  std::unique_lock<std::mutex> lock(mutex);
63 
64  while (empty()) {
65  dequeueCondition.wait(lock);
66  }
67 
68  T element = std::move(elements[tail]);
69  increment(tail);
70  --count;
71 
72  // When two threads are enqueueing, the second thread could
73  // miss the notify call if it is outside of the lock.
74  enqueueCondition.notify_one();
75  return element;
76  }
77 
78  public: T tryDequeue() override {
79  return tryDequeue(std::chrono::milliseconds(0));
80  }
81 
82  public: T tryDequeue(std::chrono::milliseconds waitTime) override {
83  std::unique_lock<std::mutex> lock(mutex);
84 
85  while (empty()) {
86  dequeueCondition.wait_for(lock, waitTime);
87  }
88 
89  if (empty()) {
90  return T();
91  }
92 
93  T element = std::move(elements[tail]);
94  increment(tail);
95  --count;
96 
97  // When two threads are enqueueing, the second thread could
98  // miss the notify call if it is outside of the lock.
99  enqueueCondition.notify_one();
100  return element;
101  }
102 
103  public: bool full() const override {
104  return count == elements.size();
105  }
106 
107  public: bool empty() const override {
108  return count == 0;
109  }
110 
112 
113  private: void increment(size_t & ptr) {
114  ++ptr;
115  ptr = ptr - (ptr == elements.size()) * elements.size();
116  }
117 
118  private: std::vector<T> elements;
119  private: size_t count;
120  private: size_t head;
121  private: size_t tail;
122  private: std::mutex mutex;
123  private: std::condition_variable enqueueCondition;
124  private: std::condition_variable dequeueCondition;
125 };
126 
127 } // namespace Balau::Container
128 
129 #endif // COM_BORA_SOFTWARE__BALAU_CONTAINER__ARRAY_BLOCKING_QUEUE
Base interface for blocking queues.
bool full() const override
Returns true if the queue is full.
Definition: ArrayBlockingQueue.hpp:103
Various container classes, apart from interprocess containers.
Definition: ArrayBlockingQueue.hpp:25
void enqueue(T &&element) override
Enqueue an object, waiting for space to be available if the queue is full.
Definition: ArrayBlockingQueue.hpp:45
T tryDequeue(std::chrono::milliseconds waitTime) override
Try to dequeue an object, waiting for the specified time if the queue is empty.
Definition: ArrayBlockingQueue.hpp:82
Base interface for blocking queues.
Definition: BlockingQueue.hpp:29
Core includes, typedefs and functions.
T dequeue() override
Dequeue an object, waiting for an object to become available if the queue is empty.
Definition: ArrayBlockingQueue.hpp:61
bool empty() const override
Returns true if the queue is empty.
Definition: ArrayBlockingQueue.hpp:107
ArrayBlockingQueue(unsigned int capacity)
Create an array blocking queue with the specified capacity.
Definition: ArrayBlockingQueue.hpp:39
A blocking queue that uses wait/notify and an array to hold the elements.
Definition: ArrayBlockingQueue.hpp:35
T tryDequeue() override
Try to dequeue an object.
Definition: ArrayBlockingQueue.hpp:78