libDwm-0.6.0
DwmPthreadQueue.hh
Go to the documentation of this file.
1 //===========================================================================
2 // @(#) $DwmPath: dwm/libDwm/tags/libDwm-0.6.0/include/DwmPthreadQueue.hh 8401 $
3 // @(#) $Id: DwmPthreadQueue.hh 8401 2016-04-17 06:44:31Z dwm $
4 //===========================================================================
5 // Copyright (c) Daniel W. McRobb 2000-2007, 2016
6 // All rights reserved.
7 //
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions
10 // are met:
11 //
12 // 1. Redistributions of source code must retain the above copyright
13 // notice, this list of conditions and the following disclaimer.
14 // 2. Redistributions in binary form must reproduce the above copyright
15 // notice, this list of conditions and the following disclaimer in the
16 // documentation and/or other materials provided with the distribution.
17 // 3. The names of the authors and copyright holders may not be used to
18 // endorse or promote products derived from this software without
19 // specific prior written permission.
20 //
21 // IN NO EVENT SHALL DANIEL W. MCROBB BE LIABLE TO ANY PARTY FOR
22 // DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
23 // INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE,
24 // EVEN IF DANIEL W. MCROBB HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
25 // DAMAGE.
26 //
27 // THE SOFTWARE PROVIDED HEREIN IS ON AN "AS IS" BASIS, AND
28 // DANIEL W. MCROBB HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
29 // UPDATES, ENHANCEMENTS, OR MODIFICATIONS. DANIEL W. MCROBB MAKES NO
30 // REPRESENTATIONS AND EXTENDS NO WARRANTIES OF ANY KIND, EITHER
31 // IMPLIED OR EXPRESS, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
32 // WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE,
33 // OR THAT THE USE OF THIS SOFTWARE WILL NOT INFRINGE ANY PATENT,
34 // TRADEMARK OR OTHER RIGHTS.
35 //===========================================================================
36 
37 //---------------------------------------------------------------------------
40 //---------------------------------------------------------------------------
41 
42 #ifndef _DWMPTHREADQUEUE_HH_
43 #define _DWMPTHREADQUEUE_HH_
44 
45 #include <deque>
46 
47 #include "DwmSysLogger.hh"
48 #include "DwmConditionVariable.hh"
49 #include "DwmMutex.hh"
50 
51 using std::deque;
52 
53 namespace Dwm {
54 
55  namespace Pthread {
56 
57  //------------------------------------------------------------------------
67  //------------------------------------------------------------------------
68  template <typename _ValueType>
69  class Queue
70  {
71  public:
72  //----------------------------------------------------------------------
74  //----------------------------------------------------------------------
76  : _queue(), _mutex(), _cv()
77  {
78  this->_maxLength = 0;
79  }
80 
81  //----------------------------------------------------------------------
83  //----------------------------------------------------------------------
85  {
86  if (! this->Lock()) {
87  SysLogger::Log(LOG_ERR,"Pthread::~Queue() failed to lock! {%s:%d}",
88  __FILE__,__LINE__);
89  }
90  this->_queue.clear();
91  this->Unlock();
92  }
93 
94  //----------------------------------------------------------------------
97  //----------------------------------------------------------------------
98  uint32_t MaxLength() const
99  {
100  return(this->_maxLength);
101  }
102 
103  //----------------------------------------------------------------------
106  //----------------------------------------------------------------------
107  uint32_t MaxLength(uint32_t maxLength)
108  {
109  this->_maxLength = maxLength;
110  return(this->_maxLength);
111  }
112 
113  //----------------------------------------------------------------------
116  //----------------------------------------------------------------------
117  bool PushBack(const _ValueType & value)
118  {
119  bool rc = false;
120  if (this->Lock()) {
121  if ((! this->_maxLength) ||
122  (this->_queue.size() < this->_maxLength)) {
123  this->_queue.push_back(value);
124  this->_cv.Broadcast();
125  rc = true;
126  }
127  this->Unlock();
128  }
129  return(rc);
130  }
131 
132  //----------------------------------------------------------------------
134  //----------------------------------------------------------------------
135  template <typename InputIterator>
136  uint32_t PushBack(InputIterator firstIter, InputIterator lastIter)
137  {
138  uint32_t rc = 0;
139  if (this->Lock()) {
140  if ((! this->_maxLength) ||
141  (this->_queue.size() < this->_maxLength)) {
142  while ((firstIter != lastIter) &&
143  ((! this->_maxLength) ||
144  (this->_queue.size() < this->_maxLength))) {
145  this->_queue.push_back(*firstIter);
146  ++firstIter;
147  ++rc;
148  }
149  if (rc)
150  this->_cv.Broadcast();
151  }
152  this->Unlock();
153  }
154  return(rc);
155  }
156 
157  //----------------------------------------------------------------------
160  //----------------------------------------------------------------------
161  bool PushFront(const _ValueType & value)
162  {
163  bool rc = false;
164  if (this->Lock()) {
165  if ((! this->_maxLength) ||
166  (this->_queue.size() < this->_maxLength)) {
167  this->_queue.push_front(value);
168  this->_cv.Broadcast();
169  rc = true;
170  }
171  this->Unlock();
172  }
173  return(rc);
174  }
175 
176  //----------------------------------------------------------------------
178  //----------------------------------------------------------------------
180  {
181  return(_cv.Signal());
182  }
183 
184  //----------------------------------------------------------------------
186  //----------------------------------------------------------------------
188  {
189  bool rc = false;
190  if (this->Lock()) {
191  rc = _cv.Wait(_mutex);
192  this->Unlock();
193  }
194  return(rc);
195  }
196 
197  //----------------------------------------------------------------------
201  //----------------------------------------------------------------------
202  bool ConditionTimedWait(const struct timespec & timeToWait)
203  {
204  bool rc = false;
205  struct timeval tv;
206  struct timezone tz;
207  gettimeofday(&tv,&tz);
208  struct timespec tspc;
209  tspc.tv_sec = tv.tv_sec + timeToWait.tv_sec +
210  ((tv.tv_usec * 1000) + timeToWait.tv_nsec) / 1000000000;
211  tspc.tv_nsec = ((tv.tv_usec * 1000) + timeToWait.tv_nsec) % 1000000000;
212  if (this->Lock()) {
213  rc = _cv.TimedWait(this->_mutex,&tspc);
214  this->Unlock();
215  }
216 
217  return(rc);
218  }
219 
220  //----------------------------------------------------------------------
223  //----------------------------------------------------------------------
224  bool PopFront(_ValueType & value)
225  {
226  bool rc = false;
227  if (this->Lock()) {
228  if (! this->_queue.empty()) {
229  value = this->_queue.front();
230  this->_queue.pop_front();
231  rc = true;
232  }
233  this->Unlock();
234  }
235  return(rc);
236  }
237 
238  //----------------------------------------------------------------------
241  //----------------------------------------------------------------------
242  bool PopBack(_ValueType & value)
243  {
244  bool rc = false;
245  if (this->Lock()) {
246  if (! this->_queue.empty()) {
247  value = this->_queue.back();
248  this->_queue.pop_back();
249  rc = true;
250  }
251  this->Unlock();
252  }
253  return(rc);
254  }
255 
256  //----------------------------------------------------------------------
259  //----------------------------------------------------------------------
261  {
262  bool rc = false;
263  if (this->Lock()) {
264  while (this->_queue.empty()) {
265  if (_cv.Wait(this->_mutex)) {
266  break;
267  }
268  }
269  rc = true;
270  this->Unlock();
271  }
272  return(rc);
273  }
274 
275  //----------------------------------------------------------------------
278  //----------------------------------------------------------------------
279  bool TimedWaitForNotEmpty(const struct timespec & timeToWait)
280  {
281  bool rc = false;
282  if (this->_queue.empty()) {
283  if (this->ConditionTimedWait(timeToWait)) {
284  if (! this->_queue.empty()) {
285  rc = true;
286  }
287  }
288  }
289  else {
290  rc = true;
291  }
292  return(rc);
293  }
294 
295  //----------------------------------------------------------------------
297  //----------------------------------------------------------------------
298  bool Empty()
299  {
300  return(this->_queue.empty());
301  }
302 
303  //----------------------------------------------------------------------
305  //----------------------------------------------------------------------
306  void RandomShuffle()
307  {
308  if (this->Lock()) {
309  random_shuffle(this->_queue.begin(), this->_queue.end());
310  this->Unlock();
311  }
312  return;
313  }
314 
315  //----------------------------------------------------------------------
317  //----------------------------------------------------------------------
318  uint32_t Copy(std::deque<_ValueType> & c)
319  {
320  uint32_t rc = 0;
321  if (! c.empty())
322  c.clear();
323 
324  if (this->Lock()) {
325  typename std::deque<_ValueType>::iterator iter = this->_queue.begin();
326  for ( ; iter != this->_queue.end(); ++iter) {
327  c.push_back(*iter);
328  ++rc;
329  }
330  this->Unlock();
331  }
332  return(rc);
333  }
334 
335  protected:
336  uint32_t _maxLength;
337  std::deque<_ValueType> _queue;
338  Mutex _mutex;
339  ConditionVariable _cv;
340 
341  //----------------------------------------------------------------------
343  //----------------------------------------------------------------------
344  bool Lock()
345  {
346  return(_mutex.Lock());
347  }
348 
349  //----------------------------------------------------------------------
351  //----------------------------------------------------------------------
352  bool Unlock()
353  {
354  return(_mutex.Unlock());
355  }
356 
357  };
358 
359 
360  } // namespace Pthread
361 
362 } // namespace Dwm
363 
364 #endif // _DWMPTHREADQUEUE_HH_
365 
366 //---------------------------- emacs settings -----------------------------
367 // Local Variables:
368 // mode: C++/la
369 // tab-width: 2
370 // indent-tabs-mode: nil
371 // c-basic-offset: 2
372 // End:
373 //-------------------------------------------------------------------------
This template provides inter-thread first-in first-out (FIFO) queueing.
Definition: DwmPthreadQueue.hh:69
bool TimedWaitForNotEmpty(const struct timespec &timeToWait)
Waits timeToWait for the queue to be non-empty.
Definition: DwmPthreadQueue.hh:279
Dwm::Pthread::Mutex class definition.
bool Empty()
Returns true if the queue is empty, else returns false.
Definition: DwmPthreadQueue.hh:298
bool Unlock()
Unlock the mutex. Returns true on success.
This class just encapsulates a condition variable (from the pthread library), with default attributes...
Definition: DwmConditionVariable.hh:59
bool PopBack(_ValueType &value)
Pops the entry from the back of the queue and stores it in value.
Definition: DwmPthreadQueue.hh:242
Queue()
Constructor.
Definition: DwmPthreadQueue.hh:75
bool PushBack(const _ValueType &value)
Inserts value on the back of the queue.
Definition: DwmPthreadQueue.hh:117
uint32_t MaxLength() const
Returns the max length of the queue.
Definition: DwmPthreadQueue.hh:98
bool Signal()
Unblocks one thread waiting for the condition variable.
bool ConditionTimedWait(const struct timespec &timeToWait)
Waits for the condition variable to be signalled or broadcasted for timeToWait to pass...
Definition: DwmPthreadQueue.hh:202
Dwm::SysLogger class definition and Syslog() macro.
bool Broadcast()
Unblocks all threads waiting for the condition variable.
static bool Log(int priority, const char *message,...)
Just like syslog(), takes a priority and a format string and variable list of arguments.
Definition: DwmBZ2IO.hh:67
bool Lock()
Lock the mutex.
~Queue()
Destructor.
Definition: DwmPthreadQueue.hh:84
bool TimedWait(Mutex &mutex, const struct timespec *abstime)
Atomically blocks the calling thread waiting on the condition variable, and unblocks the mutex specif...
Dwm::Pthread::ConditionVariable class definition.
bool ConditionSignal()
Unblocks at least one thread waiting on the condition variable.
Definition: DwmPthreadQueue.hh:179
bool ConditionWait()
Waits for the condition variable to be signalled or broadcasted.
Definition: DwmPthreadQueue.hh:187
This class just encapsulates a pthread_mutex_t (from the pthread library).
Definition: DwmMutex.hh:67
bool WaitForNotEmpty()
Blocks the calling thread until the queue contains at least one entry.
Definition: DwmPthreadQueue.hh:260
bool Wait(Mutex &mutex)
Atomically blocks the current thread waiting on the condition variable, and unblocks the mutex specif...
bool PopFront(_ValueType &value)
Pops the entry from the front of the queue and stores it in value.
Definition: DwmPthreadQueue.hh:224
bool PushFront(const _ValueType &value)
Inserts value on the front of the queue.
Definition: DwmPthreadQueue.hh:161
uint32_t MaxLength(uint32_t maxLength)
Sets and returns the max length of the queue.
Definition: DwmPthreadQueue.hh:107