Nebula
Loading...
Searching...
No Matches
safequeue.h
Go to the documentation of this file.
1#pragma once
2//------------------------------------------------------------------------------
19#include "util/queue.h"
21#include "threading/event.h"
22
23//------------------------------------------------------------------------------
24namespace Threading
25{
26template<class TYPE> class SafeQueue
27{
28public:
33
35 void operator=(const SafeQueue<TYPE>& rhs);
41 SizeT Size() const;
43 bool IsEmpty() const;
45 void Clear();
47 void Enqueue(const TYPE& e);
48 void Enqueue(TYPE&& e);
52 TYPE Dequeue();
56 TYPE Peek() const;
58 void Wait();
60 void WaitTimeout(int ms);
62 void Signal();
64 void EraseMatchingElements(const TYPE& e);
65
66protected:
71};
72
73//------------------------------------------------------------------------------
76template<class TYPE>
78 signalOnEnqueueEnabled(true)
79{
80 // empty
81}
82
83//------------------------------------------------------------------------------
86template<class TYPE>
88{
89 this->criticalSection.Enter();
90 this->queue = rhs.queue;
91 this->signalOnEnqueueEnabled = rhs.signalOnEnqueueEnabled;
92 this->criticalSection.Leave();
93}
94
95//------------------------------------------------------------------------------
98template<class TYPE> void
100{
101 this->criticalSection.Enter();
102 this->queue = rhs.queue;
103 this->signalOnEnqueueEnabled = rhs.signalOnEnqueueEnabled;
104 this->criticalSection.Leave();
105}
106
107//------------------------------------------------------------------------------
110template<class TYPE> void
112{
113 this->criticalSection.Enter();
114 this->signalOnEnqueueEnabled = b;
115 this->criticalSection.Leave();
116}
117
118//------------------------------------------------------------------------------
121template<class TYPE> void
123{
124 this->criticalSection.Enter();
125 this->queue.Clear();
126 this->criticalSection.Leave();
127}
128
129//------------------------------------------------------------------------------
132template<class TYPE> SizeT
134{
135 return this->queue.Size();
136}
137
138//------------------------------------------------------------------------------
141template<class TYPE> bool
143{
144 this->criticalSection.Enter();
145 bool isEmpty = this->queue.IsEmpty();
146 this->criticalSection.Leave();
147 return isEmpty;
148}
149
150//------------------------------------------------------------------------------
153template<class TYPE> void
155{
156 this->criticalSection.Enter();
157 this->queue.Enqueue(e);
158 this->criticalSection.Leave();
159 if (this->signalOnEnqueueEnabled)
160 {
161 this->enqueueEvent.Signal();
162 }
163}
164
165//------------------------------------------------------------------------------
168template<class TYPE> void
170{
171 this->criticalSection.Enter();
172 this->queue.Enqueue(std::move(e));
173 this->criticalSection.Leave();
174 if (this->signalOnEnqueueEnabled)
175 {
176 this->enqueueEvent.Signal();
177 }
178}
179
180//------------------------------------------------------------------------------
183template<class TYPE> void
185{
186 this->criticalSection.Enter();
187 for (auto &i : a)
188 {
189 this->queue.Enqueue(i);
190 }
191 this->criticalSection.Leave();
192 if (this->signalOnEnqueueEnabled)
193 {
194 this->enqueueEvent.Signal();
195 }
196}
197
198//------------------------------------------------------------------------------
201template<class TYPE> TYPE
203{
204 this->criticalSection.Enter();
205 TYPE e = this->queue.Dequeue();
206 this->criticalSection.Leave();
207 return e;
208}
209
210//------------------------------------------------------------------------------
213template<class TYPE> void
215{
216 this->criticalSection.Enter();
217#if NEBULA_ENABLE_PERFORMANCE_WARNINGS
218 n_warn_fmt(outArray.Capacity() >= this->queue.Size(), "SafeQueue::DequeueAll(): (PERFORMANCE) Output array is too small (%d), requires (%d), array will have to grow.\n", outArray.Capacity(), this->queue.Size());
219#endif
220 outArray.Clear();
221 for (IndexT i = 0; i < this->queue.Size(); i++)
222 {
223 outArray.Append(std::move(this->queue[i]));
224 }
225 this->queue.Clear();
226 this->criticalSection.Leave();
227}
228
229//------------------------------------------------------------------------------
232template<class TYPE> TYPE
234{
235 this->criticalSection.Enter();
236 TYPE e = this->queue.Peek();
237 this->criticalSection.Leave();
238 return e;
239}
240
241//------------------------------------------------------------------------------
244template<class TYPE> void
246{
247 if (this->signalOnEnqueueEnabled && this->IsEmpty())
248 {
249 this->enqueueEvent.Wait();
250 }
251}
252
253//------------------------------------------------------------------------------
256template<class TYPE> void
258{
259 if (this->signalOnEnqueueEnabled && this->IsEmpty())
260 {
261 this->enqueueEvent.WaitTimeout(ms);
262 }
263}
264
265//------------------------------------------------------------------------------
271template<class TYPE> void
273{
274 this->enqueueEvent.Signal();
275}
276
277//------------------------------------------------------------------------------
280template<class TYPE> void
282{
283 this->criticalSection.Enter();
284 IndexT i;
285 for (i = this->queue.Size() - 1; i >= 0; i--)
286 {
287 if (e == this->queue[i])
288 {
289 this->queue.EraseIndex(i);
290 }
291 }
292 this->criticalSection.Leave();
293}
294
295} // namespace Threading
296//------------------------------------------------------------------------------
297
Critical section objects are used to protect a portion of code from parallel execution.
Thread-safe version of Util::Queue.
Definition safequeue.h:27
void DequeueAll(Util::Array< TYPE > &outArray)
dequeue all events (only requires one lock)
Definition safequeue.h:214
void Signal()
signal the internal event, so that Wait() will return
Definition safequeue.h:272
void EnqueueArray(const Util::Array< TYPE > &a)
enqueue an array of elements
Definition safequeue.h:184
TYPE Peek() const
access to element at front of queue without removing it
Definition safequeue.h:233
void EraseMatchingElements(const TYPE &e)
erase all matching elements
Definition safequeue.h:281
SafeQueue(const SafeQueue< TYPE > &rhs)
copy constructor
Definition safequeue.h:87
bool IsEmpty() const
return true if queue is empty
Definition safequeue.h:142
void WaitTimeout(int ms)
wait until queue contains at least one element, or time-out happens
Definition safequeue.h:257
void SetSignalOnEnqueueEnabled(bool b)
enable/disable signalling on Enqueue() (default is enabled)
Definition safequeue.h:111
Event enqueueEvent
Definition safequeue.h:68
void Enqueue(const TYPE &e)
add element to the back of the queue
Definition safequeue.h:154
void Wait()
wait until queue contains at least one element
Definition safequeue.h:245
Util::Queue< TYPE > queue
Definition safequeue.h:70
bool signalOnEnqueueEnabled
Definition safequeue.h:69
TYPE Dequeue()
remove the element from the front of the queue
Definition safequeue.h:202
bool IsSignalOnEnqueueEnabled() const
return signalling-on-Enqueue() flag
SizeT Size() const
returns number of elements in the queue
Definition safequeue.h:133
void operator=(const SafeQueue< TYPE > &rhs)
assignment operator
Definition safequeue.h:99
SafeQueue()
constructor
Definition safequeue.h:77
void Clear()
remove all elements from the queue
Definition safequeue.h:122
void Enqueue(TYPE &&e)
Definition safequeue.h:169
CriticalSection criticalSection
Definition safequeue.h:67
Nebula's dynamic array class.
Definition array.h:60
const SizeT Capacity() const
get overall allocated size of array in number of elements
Definition array.h:898
void Clear()
clear array (calls destructors)
Definition array.h:1205
void Append(const TYPE &first, const ELEM_TYPE &... elements)
Append multiple elements to the end of the array.
Definition array.h:1332
Nebula's queue class (a FIFO container).
Definition queue.h:28
#define n_warn_fmt(exp, msg,...)
Definition debug.h:56
The Jobs2 system provides a set of threads and a pool of jobs from which threads can pickup work.
Definition jobs2.h:16
int SizeT
Definition types.h:49
int IndexT
Definition types.h:48