CppCommon  1.0.4.1
C++ Common Library
wait_batcher.inl
Go to the documentation of this file.
1 
9 namespace CppCommon {
10 
11 template<typename T>
12 inline WaitBatcher<T>::WaitBatcher(size_t capacity, size_t initial) : _closed(false), _capacity(capacity)
13 {
14  _batch.reserve(initial);
15 }
16 
17 template<typename T>
19 {
20  Close();
21 }
22 
23 template<typename T>
24 inline bool WaitBatcher<T>::closed() const
25 {
26  Locker<CriticalSection> locker(_cs);
27  return _closed;
28 }
29 
30 template<typename T>
31 inline size_t WaitBatcher<T>::capacity() const
32 {
33  if (_capacity > 0)
34  return _capacity;
35 
36  Locker<CriticalSection> locker(_cs);
37  return _batch.capacity();
38 }
39 
40 template<typename T>
41 inline size_t WaitBatcher<T>::size() const
42 {
43  Locker<CriticalSection> locker(_cs);
44  return _batch.size();
45 }
46 
47 template<typename T>
48 inline bool WaitBatcher<T>::Enqueue(const T& item)
49 {
50  Locker<CriticalSection> locker(_cs);
51 
52  if (_closed)
53  return false;
54 
55  do
56  {
57  if ((_capacity == 0) || (_batch.size() < _capacity))
58  {
59  _batch.push_back(item);
60  _cv1.NotifyOne();
61  return true;
62  }
63 
64  _cv2.Wait(_cs, [this]() { return (_closed || (_capacity == 0) || (_batch.size() < _capacity)); });
65 
66  } while (!_closed);
67 
68  return false;
69 }
70 
71 template<typename T>
72 inline bool WaitBatcher<T>::Enqueue(T&& item)
73 {
74  Locker<CriticalSection> locker(_cs);
75 
76  if (_closed)
77  return false;
78 
79  do
80  {
81  if ((_capacity == 0) || (_batch.size() < _capacity))
82  {
83  _batch.emplace_back(item);
84  _cv1.NotifyOne();
85  return true;
86  }
87 
88  _cv2.Wait(_cs, [this]() { return (_closed || (_capacity == 0) || (_batch.size() < _capacity)); });
89 
90  } while (!_closed);
91 
92  return false;
93 }
94 
95 template<typename T>
96 template <class InputIterator>
97 inline bool WaitBatcher<T>::Enqueue(InputIterator first, InputIterator last)
98 {
99  Locker<CriticalSection> locker(_cs);
100 
101  if (_closed)
102  return false;
103 
104  do
105  {
106  if ((_capacity == 0) || (_batch.size() < _capacity))
107  {
108  _batch.insert(_batch.end(), first, last);
109  _cv1.NotifyOne();
110  return true;
111  }
112 
113  _cv2.Wait(_cs, [this]() { return (_closed || (_capacity == 0) || (_batch.size() < _capacity)); });
114 
115  } while (!_closed);
116 
117  return false;
118 }
119 
120 template<typename T>
121 inline bool WaitBatcher<T>::Dequeue(std::vector<T>& items)
122 {
123  // Clear the result items vector
124  items.clear();
125 
126  Locker<CriticalSection> locker(_cs);
127 
128  if (_closed && _batch.empty())
129  return false;
130 
131  do
132  {
133  if (!_batch.empty())
134  {
135  // Swap batch items
136  std::swap(_batch, items);
137  _cv2.NotifyOne();
138  return true;
139  }
140 
141  _cv1.Wait(_cs, [this]() { return (_closed || !_batch.empty()); });
142 
143  } while (!_closed || !_batch.empty());
144 
145  return false;
146 }
147 
148 template<typename T>
150 {
151  Locker<CriticalSection> locker(_cs);
152  _closed = true;
153  _cv1.NotifyAll();
154  _cv2.NotifyAll();
155 }
156 
157 } // namespace CppCommon
Locker synchronization primitive.
Definition: locker.h:23
void Close()
Close the wait batcher.
bool Dequeue(std::vector< T > &items)
Dequeue all items from the wait batcher.
bool closed() const
Is wait batcher closed?
bool Enqueue(const T &item)
Enqueue an item into the wait batcher.
size_t capacity() const
Get wait batcher capacity.
WaitBatcher(size_t capacity=0, size_t initial=0)
Default class constructor.
size_t size() const
Get wait batcher size.
C++ Common project definitions.
Definition: token_bucket.h:15
void swap(FileCache &cache1, FileCache &cache2) noexcept
Definition: filecache.inl:23