c++-gtk-utils
async_queue.h
Go to the documentation of this file.
1 /* Copyright (C) 2006 to 2013 Chris Vine
2 
3 The library comprised in this file or of which this file is part is
4 distributed by Chris Vine under the GNU Lesser General Public
5 License as follows:
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Lesser General Public License
9  as published by the Free Software Foundation; either version 2.1 of
10  the License, or (at your option) any later version.
11 
12  This library is distributed in the hope that it will be useful, but
13  WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Lesser General Public License, version 2.1, for more details.
16 
17  You should have received a copy of the GNU Lesser General Public
18  License, version 2.1, along with this library (see the file LGPL.TXT
19  which came with this source code package in the c++-gtk-utils
20  sub-directory); if not, write to the Free Software Foundation, Inc.,
21  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 
23 However, it is not intended that the object code of a program whose
24 source code instantiates a template from this file or uses macros or
25 inline functions (of any length) should by reason only of that
26 instantiation or use be subject to the restrictions of use in the GNU
27 Lesser General Public License. With that in mind, the words "and
28 macros, inline functions and instantiations of templates (of any
29 length)" shall be treated as substituted for the words "and small
30 macros and small inline functions (ten lines or less in length)" in
31 the fourth paragraph of section 5 of that licence. This does not
32 affect any other reason why object code may be subject to the
33 restrictions in that licence (nor for the avoidance of doubt does it
34 affect the application of section 2 of that licence to modifications
35 of the source code in this file).
36 
37 */
38 
39 /**
40  * @file async_queue.h
41  * @brief This file provides thread-safe asynchronous queue classes.
42  *
43  * AsyncQueue is a class which provides some of the functionality of a
44  * std::queue object (but note that the AsyncQueue::pop(value_type&
45  * obj) and AsyncQueue::move_pop(value_type& obj) methods provide the
46  * popped element by reference - see the comments on that method for
47  * the reason), except that it has mutex locking of the data container
48  * so as to permit pushing and popping from different threads. It is
49  * therefore useful for passing data between threads, perhaps in
50  * response to a signal being emitted from a Notifier object. Data
51  * can be pushed or pulled by move constructor/move assignment
52  * operator or by means of a std::unique_ptr object, SharedLockPtr
53  * object or an IntrusivePtr object referencing data derived from
54  * IntrusiveLockCounter.
55  *
56  * AsyncQueueDispatch is a class which has blocking pop() and
57  * move_pop() methods, which allows it to be waited on by a dedicated
58  * event/message dispatching thread for incoming work (represented by
59  * the data pushed onto the queue). In the same way, it can be used
60  * to implement thread pools, by having threads in the pool waiting on
61  * the queue.
62  *
63  * By default the queues use a std::list object as their container
64  * because in the kind of use mentioned above they are unlikely to
65  * hold many objects but they can be changed to, say, a std::deque
66  * object by specifying it as the second template parameter.
67  */
68 
69 #ifndef CGU_ASYNC_QUEUE_H
70 #define CGU_ASYNC_QUEUE_H
71 
72 #include <queue>
73 #include <list>
74 #include <exception>
75 #include <utility> // for std::move and std::forward
76 #include <algorithm> // for std::swap
77 #include <time.h>
78 
79 #include <c++-gtk-utils/mutex.h>
80 #include <c++-gtk-utils/thread.h>
82 
83 #ifdef CGU_USE_SCHED_YIELD
84 #include <sched.h>
85 #else
86 #include <unistd.h>
87 #endif
88 
89 namespace Cgu {
90 
91 /**
92  * @class AsyncQueuePopError async_queue.h c++-gtk-utils/async_queue.h
93  * @brief An exception thrown if calling pop() on a AsyncQueue or
94  * AsyncQueueDispatch object fails because the queue is empty.
95  * @sa AsyncQueue AsyncQueueDispatch
96  */
97 
98 struct AsyncQueuePopError: public std::exception {
99  virtual const char* what() const throw() {return "AsyncQueuePopError: popping from empty AsyncQueue object\n";}
100 };
101 
102 
103 /**
104  * @class AsyncQueue async_queue.h c++-gtk-utils/async_queue.h
105  * @brief A thread-safe asynchronous queue.
106  * @sa AsyncQueueDispatch AsyncResult
107  *
108  * AsyncQueue is a class which provides some of the functionality of a
109  * std::queue object (but note that the AsyncQueue::pop(value_type&
110  * obj) and AsyncQueue::move_pop(value_type& obj) methods provide the
111  * popped element by reference - see the comments on that method for
112  * the reason), except that it has mutex locking of the data container
113  * so as to permit pushing and popping from different threads. It is
114  * therefore useful for passing data between threads, perhaps in
115  * response to a signal being emitted from a Notifier object. Data
116  * can be pushed or pulled by move constructor/move assignment
117  * operator or by means of a std::unique_ptr object, SharedLockPtr
118  * object or an IntrusivePtr object referencing data derived from
119  * IntrusiveLockCounter.
120  *
121  * By default the queue uses a std::list object as its container
122  * because in the kind of use mentioned above it is unlikely to hold
123  * many objects but it can be changed to, say, a std::deque object by
124  * specifying it as the second template parameter.
125  *
126  * If the library is installed using the
127  * \--with-glib-memory-slices-compat or
128  * \--with-glib-memory-slices-no-compat configuration options, any
129  * AsyncQueue objects constructed on free store will be constructed in
130  * glib memory slices. This does not affect the queue container
131  * itself: to change the allocator of the C++ container, a custom
132  * allocator type can be provided when the AsyncQueue object is
133  * instantiated offering the standard allocator interface. If glib
134  * memory slices are not used or no AsyncQueue objects are constructed
135  * on free store, it is not necessary to call g_thread_init() before
136  * manipulating or using an AsyncQueue object in multiple threads, but
137  * prior to glib version 2.32 glib itself (and thus glib memory
138  * slices) are not thread safe unless that function has been called.
139  */
140 
141 template <class T, class Container = std::list<T> > class AsyncQueue {
142 public:
143  typedef typename Container::value_type value_type;
144  typedef typename Container::size_type size_type;
145  typedef Container container_type;
146 private:
147 // TODO: put 'q' after 'mutex' at the next ABI break, so move
148 // construction is strongly exception safe
149  std::queue<T, Container> q;
150  mutable Thread::Mutex mutex;
151 
152 // this won't throw: it is for the user to ensure the arguments do not
153 // refer to the same mutex object
154  void lock2(Thread::Mutex& m1, Thread::Mutex& m2) {
155  m1.lock();
156  for(;;) {
157  if (!m2.trylock()) {
158  return;
159  }
160  m1.unlock();
161  // spin nicely
162 #ifdef CGU_USE_SCHED_YIELD
163  sched_yield();
164 #else
165  usleep(10);
166 #endif
167  m1.lock();
168  }
169  }
170 public:
171 /**
172  * Pushes an item onto the queue. This method has strong exception
173  * safety if the container is a std::list or std::deque container (the
174  * default is std::list), except that if std::deque is used as the
175  * container and the copy constructor, move constructor, copy
176  * assignment operator or move assignment operator of the queue item
177  * throws, it only gives the basic exception guarantee (and the basic
178  * guarantee is not given by std::deque if the queue item's move
179  * constructor throws and it uses a non-default allocator which does
180  * not provide for it to be CopyInsertable). It is thread safe.
181  * @param obj The item to be pushed onto the queue.
182  * @exception std::bad_alloc The method might throw std::bad_alloc if
183  * memory is exhausted and the system throws in that case. It might
184  * also throw if the copy constructor, move constructor, assignment
185  * operator or move assignment operator of the queue item might throw.
186  */
187  void push(const value_type& obj) {
188  Thread::Mutex::Lock lock{mutex};
189  q.push(obj);
190  }
191 
192 /**
193  * Pushes an item onto the queue. This method has strong exception
194  * safety if the container is a std::list or std::deque container (the
195  * default is std::list), except that if std::deque is used as the
196  * container and the copy constructor, move constructor, copy
197  * assignment operator or move assignment operator of the queue item
198  * throws, it only gives the basic exception guarantee (and the basic
199  * guarantee is not given by std::deque if the queue item's move
200  * constructor throws and it uses a non-default allocator which does
201  * not provide for it to be CopyInsertable). It is thread safe.
202  * @param obj The item to be pushed onto the queue.
203  * @exception std::bad_alloc The method might throw std::bad_alloc if
204  * memory is exhausted and the system throws in that case. It might
205  * also throw if the copy constructor, move constructor, assignment
206  * operator or move assignment operator of the queue item might throw.
207  *
208  * Since 2.0.0-rc5
209  */
210  void push(value_type&& obj) {
211  Thread::Mutex::Lock lock{mutex};
212  q.push(std::move(obj));
213  }
214 
215 /**
216  * Pushes an item onto the queue by constructing it in place: that is,
217  * by passing to this method the item's constructor's arguments,
218  * rather than the item itself. This method has strong exception
219  * safety if the container is a std::list or std::deque container (the
220  * default is std::list). (Technically, for a std::deque container,
221  * emplace() only offers the same exception guarantees as does push(),
222  * namely only the basic guarantee where a copy or move of the queue
223  * item throws during the call, but the purpose of emplace is to
224  * construct in place and any reasonable implementation will not copy
225  * or move the queue item.) It is thread safe.
226  * @param args The constructor arguments for the item to be pushed
227  * onto the queue.
228  * @exception std::bad_alloc The method might throw std::bad_alloc if
229  * memory is exhausted and the system throws in that case. It might
230  * also throw if the item's constructor (including any of its
231  * constructor arguments) might throw when constructing the item.
232  * @note The constructor of the item pushed onto the queue must not
233  * access any of the methods of the same queue object, or a deadlock
234  * might occur.
235  *
236  * Since 2.0.0-rc5
237  */
238  template<class... Args>
239  void emplace(Args&&... args) {
240  Thread::Mutex::Lock lock{mutex};
241  q.emplace(std::forward<Args>(args)...);
242  }
243 
244 /**
245  * Pops an item from the queue. This method has strong exception
246  * safety if the container is a std::deque or std::list container (the
247  * default is std::list), provided the destructor of a contained item
248  * does not throw. It is thread safe.
249  * @param obj A value type reference to which the item at the front of
250  * the queue will be assigned.
251  * @exception AsyncQueuePopError If the queue is empty when a pop is
252  * attempted, this method will throw AsyncQueuePopError. It might
253  * also throw if the copy assignment operator of the queue item might
254  * throw. In order to complete pop operations atomically under a
255  * single lock and to retain strong exception safety, the object into
256  * which the popped data is to be placed is passed as an argument by
257  * reference (this avoids a copy from a temporary object after the
258  * data has been extracted from the queue, which would occur if the
259  * item extracted were returned by value). It might also throw if the
260  * destructor of the queue item might throw (but that should never
261  * happen), or if the empty() method of the container type throws
262  * (which would not happen on any sane implementation).
263  */
264  void pop(value_type& obj) {
265  Thread::Mutex::Lock lock{mutex};
266  if (q.empty()) throw AsyncQueuePopError();
267  obj = q.front();
268  q.pop();
269  }
270 
271 /**
272  * Pops an item from the queue using the contained type's move
273  * assignment operator, if it has one. This method is identical to
274  * the pop() method if that type has no move assignment operator.
275  * This method has strong exception safety if the container is a
276  * std::deque or std::list container (the default is std::list),
277  * provided the destructor of a contained item does not throw and the
278  * move assignment operator of a contained item has strong exception
279  * safety. It is thread safe. Use this method in preference to the
280  * pop() method if it is known that the contained items' move
281  * assignment operator does not throw or is strongly exception safe,
282  * or if the use case does not require strong exception safety. This
283  * method must be used in place of the pop() method if the contained
284  * type has a move assignment operator but no copy assignment operator
285  * (such as a std::unique_ptr object).
286  * @param obj A value type reference to which the item at the front of
287  * the queue will be move assigned.
288  * @exception AsyncQueuePopError If the queue is empty when a pop is
289  * attempted, this method will throw AsyncQueuePopError. It might
290  * also throw if the move assignment operator of the queue item might
291  * throw, or if it has no move assignment operator and its copy
292  * assignment operator throws. In order to complete pop operations
293  * atomically under a single lock and to retain strong exception
294  * safety, the object into which the popped data is to be placed is
295  * passed as an argument by reference (this avoids a move from a
296  * temporary object after the data has been extracted from the queue,
297  * which would occur if the item extracted were returned by value).
298  * It might also throw if the destructor of the queue item might throw
299  * (but that should never happen), or if the empty() method of the
300  * container type throws (which would not happen on any sane
301  * implementation).
302  *
303  * Since 2.0.11
304  */
305  void move_pop(value_type& obj) {
306  Thread::Mutex::Lock lock{mutex};
307  if (q.empty()) throw AsyncQueuePopError();
308  obj = std::move(q.front());
309  q.pop();
310  }
311 
312 /**
313  * Discards the item at the front of the queue. This method has
314  * strong exception safety if the container is a std::deque or
315  * std::list container (the default is std::list), provided the
316  * destructor of a contained item does not throw. It is thread safe.
317  * @exception AsyncQueuePopError If the queue is empty when a pop is
318  * attempted, this method will throw AsyncQueuePopError. It might
319  * also throw if the destructor of the queue item might throw (but
320  * that should never happen), or if the empty() method of the
321  * container type throws (which would not happen on any sane
322  * implementation).
323  */
324  void pop() {
325  Thread::Mutex::Lock lock{mutex};
326  if (q.empty()) throw AsyncQueuePopError();
327  q.pop();
328  }
329 
330 /**
331  * @return Whether the queue is empty. It will not throw assuming
332  * that the empty() method of the container type does not throw, as it
333  * will not on any sane implementation.
334  * @note This method is thread safe, but the return value may not be
335  * valid if another thread has pushed to or popped from the queue
336  * before the value returned by the method is acted on. It is
337  * provided as a utility, but may not be meaningful, depending on the
338  * intended usage.
339  */
340  bool empty() const {
341  Thread::Mutex::Lock lock{mutex};
342  return q.empty();
343  }
344 
345 /**
346  * @return The number of items currently in the queue. It will not
347  * throw assuming that the size() method of the container type does
348  * not throw, as it will not on any sane implementation.
349  * @note This method is thread safe, but the return value may not be
350  * valid if another thread has pushed to or popped from the queue
351  * before the value returned by the method is acted on. It is
352  * provided as a utility, but may not be meaningful, depending on the
353  * intended usage.
354  *
355  * Since 2.0.8
356  */
357  size_type size() const {
358  Thread::Mutex::Lock lock{mutex};
359  return q.size();
360  }
361 
362 /**
363  * Swaps the contents of 'this' and 'other'. It will not throw
364  * assuming that the swap method of the container type does not throw
365  * (which the C++11 standard requires not to happen with the standard
366  * sequence containers). It is thread safe and the swap is
367  * thread-wise atomic. A non-class function
368  * Cgu::swap(Cgu::AsyncQueue&, Cgu::AsyncQueue&) method is also
369  * provided which will call this method.
370  * @param other The object to be swapped with this one.
371  *
372  * Since 2.0.8
373  */
374  void swap(AsyncQueue& other) {
375  if (this != &other) {
376  lock2(mutex, other.mutex); // doesn't throw
378  Thread::Mutex::Lock l2{other.mutex, Thread::locked};
379  q.swap(other.q);
380  }
381  }
382 
383 /**
384  * The copy assignment operator is strongly exception safe with the
385  * standard sequence containers (it uses copy and swap). It is also
386  * thread safe, as it safely locks both the assignor's and assignee's
387  * mutex to provide a thread-wise atomic assignment.
388  * @param rhs The assignor.
389  * @return The AsyncQueue object after assignment.
390  * @exception std::bad_alloc The copy constructor of the queue's
391  * container type, and so this assignment operator, might throw
392  * std::bad_alloc if memory is exhausted and the system throws in that
393  * case. This assignment operator will also throw if the copy
394  * constructor of the queue's container type throws any other
395  * exceptions, including if any copy or move constructor or copy or
396  * move assignment operator of a contained item throws.
397  * @exception Thread::MutexError This assignment operator might throw
398  * Thread::MutexError if initialization of a transitional object's
399  * contained mutex fails. (It is often not worth checking for this,
400  * as it means either memory is exhausted or pthread has run out of
401  * other resources to create new mutexes.)
402  *
403  * Since 2.0.8
404  */
406  if (this != &rhs) {
407  lock2(mutex, rhs.mutex); // doesn't throw
409  Thread::Mutex::Lock l2{rhs.mutex, Thread::locked};
410  std::queue<T, Container> temp{rhs.q};
411  q.swap(temp);
412  }
413  return *this;
414  }
415 
416 /**
417  * This move assignment operator is thread safe as regards the
418  * assignee (the object moved to), but no synchronization is carried
419  * out with respect to the rvalue assignor/movant. This is because
420  * temporaries are only visible and accessible in the thread carrying
421  * out the move operation and synchronization for them would represent
422  * pointless overhead. In a case where the user uses std::move to
423  * force a move from a named object, and that named object's lifetime
424  * is managed by (or the object is otherwise accessed by) a different
425  * thread than the one making the move, the user must carry out her
426  * own synchronization with respect to that different thread, both to
427  * ensure that a consistent view of the the named object is obtained
428  * and because that object will be mutated by the move. This method
429  * invokes std::queue's move assignment operator, and therefore has
430  * the same exception safety as the standard library's implementation
431  * of that operator. It will not normally throw unless a custom
432  * allocator is used which throws on move assignment, or the
433  * destructor of a contained item throws.
434  * @param rhs The assignor/movant.
435  * @return The AsyncQueue object after move assignment.
436  *
437  * Since 2.0.8
438  */
440  Thread::Mutex::Lock lock{mutex};
441  q = std::move(rhs.q);
442  return *this;
443  }
444 
445 /**
446  * @exception std::bad_alloc The default constructor might throw
447  * std::bad_alloc if memory is exhausted and the system throws in that
448  * case.
449  * @exception Thread::MutexError The default constructor might throw
450  * Thread::MutexError if initialization of the contained mutex fails.
451  * (It is often not worth checking for this, as it means either memory
452  * is exhausted or pthread has run out of other resources to create
453  * new mutexes.)
454  */
455  AsyncQueue() = default;
456 
457 /**
458  * As regards thread safety, the move constructor does not synchronize
459  * with respect to the initializing rvalue. This is because
460  * temporaries are only visible and accessible in the thread carrying
461  * out the move operation and synchronization for them would represent
462  * pointless overhead. In a case where a user uses std::move to force
463  * a move from a named object, and that named object's lifetime is
464  * managed by (or the object is otherwise accessed by) a different
465  * thread than the one making the move, the user must carry out her
466  * own synchronization with respect to that different thread, both to
467  * ensure that a consistent view of the the named object is obtained
468  * and because that object will be mutated by the move.
469  * @param rhs The AsyncQueue object to be moved.
470  * @exception Thread::MutexError The move constructor might throw
471  * Thread::MutexError if initialization of the contained mutex fails.
472  * (It is often not worth checking for this, as it means either memory
473  * is exhausted or pthread has run out of other resources to create
474  * new mutexes.) It might also throw if the queue's container type's
475  * move constructor might throw, but it should not do that unless a
476  * custom allocator is in use.
477  * @note If this constructor throws Thread::MutexError, and a named
478  * object is moved using std::move, this constructor is not strongly
479  * exception safe (items in the moved queue will be lost). Fixing
480  * this efficiently requires changing the order of construction of
481  * data members of this class, which cannot be done until the next ABI
482  * break for this library as it would alter object layout. As noted
483  * above, in most cases the possibility of Thread::MutexError throwing
484  * can be ignored, but where that is not the case and strong exception
485  * safety is wanted, the user should either not employ std::move with
486  * named objects when invoking this class's constructors, or should
487  * construct an AsyncQueue object using the default constructor and
488  * then move assign to it.
489  *
490  * Since 2.0.8
491  */
492  AsyncQueue(AsyncQueue&& rhs): q(std::move(rhs.q)) {}
493 
494 /**
495  * The copy constructor is thread safe, as it locks the initializing
496  * object's mutex to obtain a consistent view of it.
497  * @param rhs The AsyncQueue object to be copied.
498  * @exception std::bad_alloc The copy constructor of the queue's
499  * container type, and so this constructor, might throw std::bad_alloc
500  * if memory is exhausted and the system throws in that case. It will
501  * also throw if the copy constructor of the queue's container type
502  * throws any other exceptions, including if any copy or move
503  * constructor or copy or move assignment operator of a contained item
504  * throws.
505  * @exception Thread::MutexError The copy constructor might throw
506  * Thread::MutexError if initialization of the contained mutex fails.
507  * (It is often not worth checking for this, as it means either memory
508  * is exhausted or pthread has run out of other resources to create
509  * new mutexes.)
510  *
511  * Since 2.0.8
512  */
513  // we use the comma operator here to lock the mutex and call the
514  // copy constructor: the lock will be retained until the end of the
515  // full expression in which it is lexically situated, namely until
516  // the end of q's constructor - see C++11 1.9/10 and 12.2/3
517  AsyncQueue(const AsyncQueue& rhs): q((Thread::Mutex::Lock(rhs.mutex), rhs.q)) {}
518 
519 /**
520  * The destructor does not throw unless the destructor of a contained
521  * item throws. It is thread safe (any thread may delete the
522  * AsyncQueue object).
523  */
525  // lock and unlock the mutex in the destructor so that we have an
526  // acquire operation to ensure that when the std::queue object is
527  // destroyed memory is synchronised, so any thread may destroy the
528  // AsyncQueue object
529  Thread::Mutex::Lock lock{mutex};
530  }
531 
532 /* Only has effect if --with-glib-memory-slices-compat or
533  * --with-glib-memory-slices-no-compat option picked */
535 };
536 
537 /**
538  * @class AsyncQueueDispatch async_queue.h c++-gtk-utils/async_queue.h
539  * @brief A thread-safe asynchronous queue with a blocking pop()
540  * method.
541  * @sa AsyncQueue AsyncResult
542  *
543  * AsyncQueueDispatch is a class which has blocking pop_dispatch()
544  * and move_pop_dispatch() methods, which allows it to be waited on by a dedicated
545  * event/message dispatching thread for incoming work (represented by
546  * the data pushed onto the queue). In the same way, it can be used
547  * to implement thread pools, by having threads in the pool waiting on
548  * the queue. The AsyncResult class can be useful for passing results
549  * between threads in conjunction with AsyncQueueDispatch (the
550  * documentation on AsyncResult gives an example).
551  *
552  * By default the queue uses a std::list object as its container
553  * because in the kind of use mentioned above it is unlikely to hold
554  * many objects but it can be changed to, say, a std::deque object by
555  * specifying it as the second template parameter.
556  *
557  * If the library is installed using the
558  * \--with-glib-memory-slices-compat or
559  * \--with-glib-memory-slices-no-compat configuration options, any
560  * AsyncQueueDispatch objects constructed on free store will be
561  * constructed in glib memory slices. This does not affect the queue
562  * container itself: to change the allocator of the C++ container, a
563  * custom allocator type can be provided when the AsyncQueueDispatch
564  * object is instantiated offering the standard allocator interface.
565  * If glib memory slices are not used or no AsyncQueueDispatch objects
566  * are constructed on free store, it is not necessary to call
567  * g_thread_init() before manipulating or using an AsyncQueueDispatch
568  * object in multiple threads, but prior to glib version 2.32 glib
569  * itself (and thus glib memory slices) are not thread safe unless
570  * that function has been called.
571  */
572 
573 template <class T, class Container = std::list<T> > class AsyncQueueDispatch {
574 public:
575  typedef typename Container::value_type value_type;
576  typedef typename Container::size_type size_type;
577  typedef Container container_type;
578 private:
579 // TODO: put 'q' after 'mutex' and 'cond' at the next ABI break, so
580 // move construction is strongly exception safe
581  std::queue<T, Container> q;
582  mutable Thread::Mutex mutex;
583  Thread::Cond cond;
584 
585 // this won't throw: it is for the user to ensure the arguments do not
586 // refer to the same mutex object
587  void lock2(Thread::Mutex& m1, Thread::Mutex& m2) {
588  m1.lock();
589  for(;;) {
590  if (!m2.trylock()) {
591  return;
592  }
593  m1.unlock();
594  // spin nicely
595 #ifdef CGU_USE_SCHED_YIELD
596  sched_yield();
597 #else
598  usleep(10);
599 #endif
600  m1.lock();
601  }
602  }
603 public:
604 /**
605  * Pushes an item onto the queue. This method has strong exception
606  * safety if the container is a std::list or std::deque container (the
607  * default is std::list), except that if std::deque is used as the
608  * container and the copy constructor, move constructor, copy
609  * assignment operator or move assignment operator of the queue item
610  * throws, it only gives the basic exception guarantee (and the basic
611  * guarantee is not given by std::deque if the queue item's move
612  * constructor throws and it uses a non-default allocator which does
613  * not provide for it to be CopyInsertable). It is thread safe.
614  * @param obj The item to be pushed onto the queue.
615  * @exception std::bad_alloc The method might throw std::bad_alloc if
616  * memory is exhausted and the system throws in that case. It might
617  * also throw if the copy constructor, move constructor, assignment
618  * operator or move assignment operator of the queue item might throw.
619  */
620  void push(const value_type& obj) {
621  Thread::Mutex::Lock lock{mutex};
622  q.push(obj);
623  cond.signal();
624  }
625 
626 /**
627  * Pushes an item onto the queue. This method has strong exception
628  * safety if the container is a std::list or std::deque container (the
629  * default is std::list), except that if std::deque is used as the
630  * container and the copy constructor, move constructor, copy
631  * assignment operator or move assignment operator of the queue item
632  * throws, it only gives the basic exception guarantee (and the basic
633  * guarantee is not given by std::deque if the queue item's move
634  * constructor throws and it uses a non-default allocator which does
635  * not provide for it to be CopyInsertable). It is thread safe.
636  * @param obj The item to be pushed onto the queue.
637  * @exception std::bad_alloc The method might throw std::bad_alloc if
638  * memory is exhausted and the system throws in that case. It might
639  * also throw if the copy constructor, move constructor, assignment
640  * operator or move assignment operator of the queue item might throw.
641  *
642  * Since 2.0.0-rc5
643  */
644  void push(value_type&& obj) {
645  Thread::Mutex::Lock lock{mutex};
646  q.push(std::move(obj));
647  cond.signal();
648  }
649 
650 /**
651  * Pushes an item onto the queue by constructing it in place: that is,
652  * by passing to this method the item's constructor's arguments,
653  * rather than the item itself. This method has strong exception
654  * safety if the container is a std::list or std::deque container (the
655  * default is std::list). (Technically, for a std::deque container,
656  * emplace() only offers the same exception guarantees as does push(),
657  * namely only the basic guarantee where a copy or move of the queue
658  * item throws during the call, but the purpose of emplace is to
659  * construct in place and any reasonable implementation will not copy
660  * or move the queue item.) It is thread safe.
661  * @param args The constructor arguments for the item to be pushed
662  * onto the queue.
663  * @exception std::bad_alloc The method might throw std::bad_alloc if
664  * memory is exhausted and the system throws in that case. It might
665  * also throw if the item's constructor (including any of its
666  * constructor arguments) might throw when constructing the item.
667  * @note The constructor of the item pushed onto the queue must not
668  * access any of the methods of the same queue object, or a deadlock
669  * might occur.
670  *
671  * Since 2.0.0-rc5
672  */
673  template<class... Args>
674  void emplace(Args&&... args) {
675  Thread::Mutex::Lock lock{mutex};
676  q.emplace(std::forward<Args>(args)...);
677  cond.signal();
678  }
679 
680 /**
681  * Pops an item from the queue. This method has strong exception
682  * safety if the container is a std::deque or std::list container (the
683  * default is std::list), provided the destructor of a contained item
684  * does not throw. It is thread safe.
685  * @param obj A value type reference to which the item at the front of
686  * the queue will be assigned.
687  * @exception AsyncQueuePopError If the queue is empty when a pop is
688  * attempted, this method will throw AsyncQueuePopError. It might
689  * also throw if the copy assignment operator of the queue item might
690  * throw. In order to complete pop operations atomically under a
691  * single lock and to retain strong exception safety, the object into
692  * which the popped data is to be placed is passed as an argument by
693  * reference (this avoids a copy from a temporary object after the
694  * data has been extracted from the queue, which would occur if the
695  * item extracted were returned by value). It might also throw if the
696  * destructor of the queue item might throw (but that should never
697  * happen), or if the empty() method of the container type throws
698  * (which would not happen on any sane implementation).
699  */
700  void pop(value_type& obj) {
701  Thread::Mutex::Lock lock{mutex};
702  if (q.empty()) throw AsyncQueuePopError();
703  obj = q.front();
704  q.pop();
705  }
706 
707 /**
708  * Pops an item from the queue using the contained type's move
709  * assignment operator, if it has one. This method is identical to
710  * the pop() method if that type has no move assignment operator.
711  * This method has strong exception safety if the container is a
712  * std::deque or std::list container (the default is std::list),
713  * provided the destructor of a contained item does not throw and the
714  * move assignment operator of a contained item has strong exception
715  * safety. It is thread safe. Use this method in preference to the
716  * pop() method if it is known that the contained items' move
717  * assignment operator does not throw or is strongly exception safe,
718  * or if the use case does not require strong exception safety. This
719  * method must be used in place of the pop() method if the contained
720  * type has a move assignment operator but no copy assignment operator
721  * (such as a std::unique_ptr object).
722  * @param obj A value type reference to which the item at the front of
723  * the queue will be move assigned.
724  * @exception AsyncQueuePopError If the queue is empty when a pop is
725  * attempted, this method will throw AsyncQueuePopError. It might
726  * also throw if the move assignment operator of the queue item might
727  * throw, or if it has no move assignment operator and its copy
728  * assignment operator throws. In order to complete pop operations
729  * atomically under a single lock and to retain strong exception
730  * safety, the object into which the popped data is to be placed is
731  * passed as an argument by reference (this avoids a move from a
732  * temporary object after the data has been extracted from the queue,
733  * which would occur if the item extracted were returned by value).
734  * It might also throw if the destructor of the queue item might throw
735  * (but that should never happen), or if the empty() method of the
736  * container type throws (which would not happen on any sane
737  * implementation).
738  *
739  * Since 2.0.11
740  */
741  void move_pop(value_type& obj) {
742  Thread::Mutex::Lock lock{mutex};
743  if (q.empty()) throw AsyncQueuePopError();
744  obj = std::move(q.front());
745  q.pop();
746  }
747 
748 /**
749  * Pops an item from the queue. If the queue is empty, it will block
750  * until an item becomes available. If it blocks, the wait comprises
751  * a cancellation point. This method is cancellation safe if the
752  * stack unwinds on cancellation, as cancellation is blocked while the
753  * queue is being operated on after coming out of a wait. This method
754  * has strong exception safety if the container is a std::deque or
755  * std::list container (the default is std::list), provided the
756  * destructor of a contained item does not throw. It is thread safe.
757  * @param obj A value type reference to which the item at the front of
758  * the queue will be assigned. This method might throw if the copy
759  * assignment operator of the queue item might throw. In order to
760  * complete pop operations atomically under a single lock and to
761  * retain strong exception safety, the object into which the popped
762  * data is to be placed is passed as an argument by reference (this
763  * avoids a copy from a temporary object after the data has been
764  * extracted from the queue, which would occur if the item extracted
765  * were returned by value). It might also throw if the destructor of
766  * the queue item might throw (but that should never happen), or if
767  * the empty() method of the container type throws (which would not
768  * happen on any sane implementation).
769  */
771  Thread::Mutex::Lock lock{mutex};
772  while (q.empty()) cond.wait(mutex);
774  obj = q.front();
775  q.pop();
776  }
777 
778 /**
779  * Pops an item from the queue using the contained type's move
780  * assignment operator, if it has one (this method is identical to the
781  * pop_dispatch() method if that type has no move assignment
782  * operator). If the queue is empty, it will block until an item
783  * becomes available. If it blocks, the wait comprises a cancellation
784  * point. This method is cancellation safe if the stack unwinds on
785  * cancellation, as cancellation is blocked while the queue is being
786  * operated on after coming out of a wait. This method has strong
787  * exception safety if the container is a std::deque or std::list
788  * container (the default is std::list), provided the destructor of a
789  * contained item does not throw and the move assignment operator of a
790  * contained item has strong exception safety. It is thread safe.
791  * Use this method in preference to the pop_dispatch() method if it is
792  * known that the contained items' move assignment operator does not
793  * throw or is strongly exception safe, or if the use case does not
794  * require strong exception safety. This method must be used in place
795  * of the pop_dispatch() method if the contained type has a move
796  * assignment operator but no copy assignment operator (such as a
797  * std::unique_ptr object).
798  * @param obj A value type reference to which the item at the front of
799  * the queue will be move assigned. This method might throw if the
800  * move assignment operator of the queue item might throw, or if it
801  * has no move assignment operator and its copy assignment operator
802  * throws. In order to complete pop operations atomically under a
803  * single lock and to retain strong exception safety, the object into
804  * which the popped data is to be placed is passed as an argument by
805  * reference (this avoids a move from a temporary object after the
806  * data has been extracted from the queue, which would occur if the
807  * item extracted were returned by value). It might also throw if the
808  * destructor of the queue item might throw (but that should never
809  * happen), or if the empty() method of the container type throws
810  * (which would not happen on any sane implementation).
811  *
812  * Since 2.0.11
813  */
815  Thread::Mutex::Lock lock{mutex};
816  while (q.empty()) cond.wait(mutex);
818  obj = std::move(q.front());
819  q.pop();
820  }
821 
822 /**
823  * Pops an item from the queue. If the queue is empty, it will block
824  * until an item becomes available or until the timeout expires. If
825  * it blocks, the wait comprises a cancellation point. This method is
826  * cancellation safe if the stack unwinds on cancellation, as
827  * cancellation is blocked while the queue is being operated on after
828  * coming out of a wait. This method has strong exception safety if
829  * the container is a std::deque or std::list container (the default
830  * is std::list), provided the destructor of a contained item does not
831  * throw. It is thread safe.
832  * @param obj A value type reference to which the item at the front of
833  * the queue will be assigned. This method might throw if the copy
834  * assignment operator of the queue item might throw. In order to
835  * complete pop operations atomically under a single lock and to
836  * retain strong exception safety, the object into which the popped
837  * data is to be placed is passed as an argument by reference (this
838  * avoids a copy from a temporary object after the data has been
839  * extracted from the queue, which would occur if the item extracted
840  * were returned by value). It might also throw if the destructor of
841  * the queue item might throw (but that should never happen), or if
842  * the empty() method of the container type throws (which would not
843  * happen on any sane implementation).
844  * @param millisec The timeout interval, in milliseconds.
845  * @return If the timeout expires without an item becoming available,
846  * the method will return true. If an item from the queue is
847  * extracted, it returns false.
848  */
849  bool pop_timed_dispatch(value_type& obj, unsigned int millisec) {
850  timespec ts;
851  Thread::Cond::get_abs_time(ts, millisec);
852  Thread::Mutex::Lock lock{mutex};
853  while (q.empty()) {
854  if (cond.timed_wait(mutex, ts)) return true;
855  }
857  obj = q.front();
858  q.pop();
859  return false;
860  }
861 
862 /**
863  * Pops an item from the queue using the contained type's move
864  * assignment operator, if it has one (this method is identical to the
865  * pop_timed_dispatch() method if that type has no move assignment
866  * operator). If the queue is empty, it will block until an item
867  * becomes available or until the timeout expires. If it blocks, the
868  * wait comprises a cancellation point. This method is cancellation
869  * safe if the stack unwinds on cancellation, as cancellation is
870  * blocked while the queue is being operated on after coming out of a
871  * wait. This method has strong exception safety if the container is
872  * a std::deque or std::list container (the default is std::list),
873  * provided the destructor of a contained item does not throw and the
874  * move assignment operator of a contained item has strong exception
875  * safety. It is thread safe. Use this method in preference to the
876  * pop_timed_dispatch() method if it is known that the contained
877  * items' move assignment operator does not throw or is strongly
878  * exception safe, or if the use case does not require strong
879  * exception safety. This method must be used in place of the
880  * pop_timed_dispatch() method if the contained type has a move
881  * assignment operator but no copy assignment operator (such as a
882  * std::unique_ptr object).
883  * @param obj A value type reference to which the item at the front of
884  * the queue will be move assigned. This method might throw if the
885  * move assignment operator of the queue item might throw, or if it
886  * has no move assignment operator and its copy assignment operator
887  * throws. In order to complete pop operations atomically under a
888  * single lock and to retain strong exception safety, the object into
889  * which the popped data is to be placed is passed as an argument by
890  * reference (this avoids a move from a temporary object after the
891  * data has been extracted from the queue, which would occur if the
892  * item extracted were returned by value). It might also throw if the
893  * destructor of the queue item might throw (but that should never
894  * happen), or if the empty() method of the container type throws
895  * (which would not happen on any sane implementation).
896  * @param millisec The timeout interval, in milliseconds.
897  * @return If the timeout expires without an item becoming available,
898  * the method will return true. If an item from the queue is
899  * extracted, it returns false.
900  *
901  * Since 2.0.11
902  */
903  bool move_pop_timed_dispatch(value_type& obj, unsigned int millisec) {
904  timespec ts;
905  Thread::Cond::get_abs_time(ts, millisec);
906  Thread::Mutex::Lock lock{mutex};
907  while (q.empty()) {
908  if (cond.timed_wait(mutex, ts)) return true;
909  }
911  obj = std::move(q.front());
912  q.pop();
913  return false;
914  }
915 
916 /**
917  * Discards the item at the front of the queue. This method has
918  * strong exception safety if the container is a std::deque or
919  * std::list container (the default is std::list), provided the
920  * destructor of a contained item does not throw. It is thread safe.
921  * @exception AsyncQueuePopError If the queue is empty when a pop is
922  * attempted, this method will throw AsyncQueuePopError. It might
923  * also throw if the destructor of the queue item might throw (but
924  * that should never happen), or if the empty() method of the
925  * container type throws (which would not happen on any sane
926  * implementation).
927  */
928  void pop() {
929  Thread::Mutex::Lock lock{mutex};
930  if (q.empty()) throw AsyncQueuePopError();
931  q.pop();
932  }
933 
934 /**
935  * @return Whether the queue is empty. It will not throw assuming
936  * that the empty() method of the container type does not throw, as it
937  * will not on any sane implementation.
938  * @note This method is thread safe, but the return value may not be
939  * valid if another thread has pushed to or popped from the queue
940  * before the value returned by the method is acted on. It is
941  * provided as a utility, but may not be meaningful, depending on the
942  * intended usage.
943  */
944  bool empty() const {
945  Thread::Mutex::Lock lock{mutex};
946  return q.empty();
947  }
948 
949 /**
950  * @return The number of items currently in the queue. It will not
951  * throw assuming that the size() method of the container type does
952  * not throw, as it will not on any sane implementation.
953  * @note This method is thread safe, but the return value may not be
954  * valid if another thread has pushed to or popped from the queue
955  * before the value returned by the method is acted on. It is
956  * provided as a utility, but may not be meaningful, depending on the
957  * intended usage.
958  *
959  * Since 2.0.8
960  */
961  size_type size() const {
962  Thread::Mutex::Lock lock{mutex};
963  return q.size();
964  }
965 
966 /**
967  * Swaps the contents of 'this' and 'other'. It will not throw
968  * assuming that the swap method of the container type does not throw
969  * (which the C++11 standard requires not to happen with the standard
970  * sequence containers). It is thread safe and the swap is
971  * thread-wise atomic. A non-class function
972  * Cgu::swap(Cgu::AsyncQueue&, Cgu::AsyncQueue&) method is also
973  * provided which will call this method.
974  * @param other The object to be swapped with this one.
975  * @note An object swapped does not, by virtue of the swap, inherit
976  * any threads waiting on the other one. However if threads were
977  * waiting on a swapped object prior to the swap, and it acquires
978  * items by virtue of the swap, the waiting threads will unblock and
979  * extract those items.
980  *
981  * Since 2.0.8
982  */
983  void swap(AsyncQueueDispatch& other) {
984  if (this != &other) {
985  lock2(mutex, other.mutex); // doesn't throw
987  Thread::Mutex::Lock l2{other.mutex, Thread::locked};
988  q.swap(other.q);
989  if (!q.empty()) cond.broadcast();
990  if (!other.q.empty()) other.cond.broadcast();
991  }
992  }
993 
994 /**
995  * The copy assignment operator is strongly exception safe with the
996  * standard sequence containers (it uses copy and swap). It is also
997  * thread safe, as it safely locks both the assignor's and assignee's
998  * mutex to provide a thread-wise atomic assignment.
999  * @param rhs The assignor.
1000  * @return The AsyncQueueDispatch object after assignment.
1001  * @exception std::bad_alloc The copy constructor of the queue's
1002  * container type, and so this assignment operator, might throw
1003  * std::bad_alloc if memory is exhausted and the system throws in that
1004  * case. This assignment operator will also throw if the copy
1005  * constructor of the queue's container type throws any other
1006  * exceptions, including if any copy or move constructor or copy or
1007  * move assignment operator of a contained item throws.
1008  * @exception Thread::MutexError This assignment operator might
1009  * throw Thread::MutexError if initialization of a transitional
1010  * object's contained mutex fails. (It is often not worth checking
1011  * for this, as it means either memory is exhausted or pthread has run
1012  * out of other resources to create new mutexes.)
1013  * @exception Thread::CondError This assignment operator might throw
1014  * Thread::CondError if initialisation of a transitional object's
1015  * contained condition variable fails. (It is often not worth
1016  * checking for this, as it means either memory is exhausted or
1017  * pthread has run out of other resources to create new condition
1018  * variables.)
1019  * @note The assignee does not, by virtue of the assignment, inherit
1020  * any threads waiting on the assignor. However, if prior to the
1021  * assignment threads were waiting on the assignee and the assignee
1022  * acquires items from the assignor as a result of the assignment, the
1023  * waiting threads will unblock and extract those items.
1024  *
1025  * Since 2.0.8
1026  */
1028  if (this != &rhs) {
1029  lock2(mutex, rhs.mutex); // doesn't throw
1031  Thread::Mutex::Lock l2{rhs.mutex, Thread::locked};
1032  std::queue<T, Container> temp{rhs.q};
1033  q.swap(temp);
1034  if (!q.empty()) cond.broadcast();
1035  }
1036  return *this;
1037  }
1038 
1039 /**
1040  * This move assignment operator is thread safe as regards the
1041  * assignee (the object moved to), but no synchronization is carried
1042  * out with respect to the rvalue assignor/movant. This is because
1043  * temporaries are only visible and accessible in the thread carrying
1044  * out the move operation and synchronization for them would represent
1045  * pointless overhead. In a case where the user uses std::move to
1046  * force a move from a named object, and that named object's lifetime
1047  * is managed by (or the object is otherwise accessed by) a different
1048  * thread than the one making the move, the user must carry out her
1049  * own synchronization with respect to that different thread, both to
1050  * ensure that a consistent view of the the named object is obtained
1051  * and because that object will be mutated by the move. This method
1052  * invokes std::queue's move assignment operator, and therefore has
1053  * the same exception safety as the standard library's implementation
1054  * of that operator. It will not normally throw unless a custom
1055  * allocator is used which throws on move assignment, or the
1056  * destructor of a contained item throws.
1057  * @param rhs The assignor/movant.
1058  * @return The AsyncQueueDispatch object after move assignment.
1059  * @note The assignee does not, by virtue of the move, inherit any
1060  * threads waiting on the assignor/movant. However, if prior to the
1061  * move threads were waiting on the assignee and the assignee acquires
1062  * items from the assignor/movant as a result of the move, from
1063  * version 2.0.9 the waiting threads will unblock and extract those
1064  * items (such unblocking on move assignment did not happen with
1065  * version 2.0.8, which was a bug).
1066  *
1067  * Since 2.0.8
1068  */
1070  Thread::Mutex::Lock lock{mutex};
1071  q = std::move(rhs.q);
1072  if (!q.empty()) cond.broadcast();
1073  return *this;
1074  }
1075 
1076 /**
1077  * @exception std::bad_alloc The default constructor might throw this
1078  * exception if memory is exhausted and the system throws in that
1079  * case.
1080  * @exception Thread::MutexError The default constructor might throw
1081  * this exception if initialisation of the contained mutex fails. (It
1082  * is often not worth checking for this, as it means either memory is
1083  * exhausted or pthread has run out of other resources to create new
1084  * mutexes.)
1085  * @exception Thread::CondError The default constructor might throw
1086  * this exception if initialisation of the contained condition
1087  * variable fails. (It is often not worth checking for this, as it
1088  * means either memory is exhausted or pthread has run out of other
1089  * resources to create new condition variables.)
1090  */
1091  AsyncQueueDispatch() = default;
1092 
1093 /**
1094  * As regards thread safety, the move constructor does not synchronize
1095  * with respect to the initializing rvalue. This is because
1096  * temporaries are only visible and accessible in the thread carrying
1097  * out the move operation and synchronization for them would represent
1098  * pointless overhead. In a case where a user uses std::move to force
1099  * a move from a named object, and that named object's lifetime is
1100  * managed by (or the object is otherwise accessed by) a different
1101  * thread than the one making the move, the user must carry out her
1102  * own synchronization with respect to that different thread, both to
1103  * ensure that a consistent view of the the named object is obtained
1104  * and because that object will be mutated by the move.
1105  * @param rhs The AsyncQueueDispatch object to be moved.
1106  * @exception Thread::MutexError The move constructor might throw
1107  * Thread::MutexError if initialization of the contained mutex fails.
1108  * (It is often not worth checking for this, as it means either memory
1109  * is exhausted or pthread has run out of other resources to create
1110  * new mutexes.) It might also throw if the queue's container type's
1111  * move constructor might throw, but it should not do that unless a
1112  * custom allocator is in use.
1113  * @exception Thread::CondError The move constructor might throw this
1114  * exception if initialisation of the contained condition variable
1115  * fails. (It is often not worth checking for this, as it means
1116  * either memory is exhausted or pthread has run out of other
1117  * resources to create new condition variables.) It might also throw
1118  * if the queue's container type's move constructor might throw, but
1119  * it should not do that unless a custom allocator is in use.
1120  * @note If this constructor throws Thread::MutexError or
1121  * Thread::CondError, and a named object is moved using std::move,
1122  * this constructor is not strongly exception safe (items in the moved
1123  * queue will be lost). Fixing this efficiently requires changing the
1124  * order of construction of data members of this class, which cannot
1125  * be done until the next ABI break for this library as it would alter
1126  * object layout. As noted above, in most cases the possibility of
1127  * Thread::MutexError or Thread::CondError throwing can be ignored,
1128  * but where that is not the case and strong exception safety is
1129  * wanted, the user should either not employ std::move with named
1130  * objects when invoking this class's constructors, or should
1131  * construct an AsyncQueueDispatch object using the default
1132  * constructor and then move assign to it.
1133  *
1134  * Since 2.0.8
1135  */
1136  AsyncQueueDispatch(AsyncQueueDispatch&& rhs): q(std::move(rhs.q)) {}
1137 
1138 /**
1139  * The copy constructor is thread safe, as it locks the initializing
1140  * object's mutex to obtain a consistent view of it.
1141  * @param rhs The AsyncQueueDispatch object to be copied.
1142  * @exception std::bad_alloc The copy constructor of the queue's
1143  * container type, and so this constructor, might throw std::bad_alloc
1144  * if memory is exhausted and the system throws in that case. It will
1145  * also throw if the copy constructor of the queue's container type
1146  * throws any other exceptions, including if any copy or move
1147  * constructor or copy or move assignment operator of a contained item
1148  * throws.
1149  * @exception Thread::MutexError The copy constructor might throw
1150  * Thread::MutexError if initialization of the contained mutex fails.
1151  * (It is often not worth checking for this, as it means either memory
1152  * is exhausted or pthread has run out of other resources to create
1153  * new mutexes.)
1154  * @exception Thread::CondError The copy constructor might throw this
1155  * exception if initialisation of the contained condition variable
1156  * fails. (It is often not worth checking for this, as it means
1157  * either memory is exhausted or pthread has run out of other
1158  * resources to create new condition variables.)
1159  *
1160  * Since 2.0.8
1161  */
1162  // we use the comma operator here to lock the mutex and call the
1163  // copy constructor: the lock will be retained until the end of the
1164  // full expression in which it is lexically situated, namely until
1165  // the end of q's constructor - see C++11 1.9/10 and 12.2/3
1167  q((Thread::Mutex::Lock(rhs.mutex), rhs.q)) {}
1168 
1169 /**
1170  * The destructor does not throw unless the destructor of a contained
1171  * item throws. It is thread safe (any thread may delete the
1172  * AsyncQueueDispatch object). Destroying an AsyncQueueDispatch
1173  * object on which another thread is currently blocked results in
1174  * undefined behavior.
1175  */
1177  // lock and unlock the mutex in the destructor so that we have an
1178  // acquire operation to ensure that when the std::queue object is
1179  // destroyed memory is synchronised, so any thread may destroy the
1180  // AsyncQueueDispatch object
1181  Thread::Mutex::Lock lock{mutex};
1182  }
1183 
1184 /* Only has effect if --with-glib-memory-slices-compat or
1185  * --with-glib-memory-slices-no-compat option picked */
1187 };
1188 
1189 /**
1190  * Swaps the contents of two AsyncQueue objects. It will not throw
1191  * assuming that the swap method of the container type does not throw
1192  * (which the C++11 standard requires not to happen with the standard
1193  * sequence containers). It is thread safe and the swap is
1194  * thread-wise atomic.
1195  * @param q1 An object to be swapped with the other.
1196  * @param q2 An object to be swapped with the other.
1197  * @note Calling std::swap on AsyncQueue objects is thread safe but
1198  * does not provide a thread-wise atomic swap (the swapped objects may
1199  * not be mirror images if during the execution of std::swap's default
1200  * algorithm one of them has been modified), although in many cases
1201  * that doesn't matter. If swap() is called without a namespace
1202  * qualifier, argument dependent look-up will pick this one correctly.
1203  *
1204  * Since 2.0.8
1205  */
1206 template <class T, class Container>
1209  q1.swap(q2);
1210 }
1211 
1212 /**
1213  * Swaps the contents of two AsyncQueueDispatch objects. It will not
1214  * throw assuming that the swap method of the container type does not
1215  * throw (which the C++11 standard requires not to happen with the
1216  * standard sequence containers). It is thread safe and the swap is
1217  * thread-wise atomic.
1218  * @param q1 An object to be swapped with the other.
1219  * @param q2 An object to be swapped with the other.
1220  * @note 1. An object swapped does not, by virtue of the swap, inherit
1221  * any threads waiting on the other one. However if threads were
1222  * waiting on a swapped object prior to the swap, and it acquires
1223  * items by virtue of the swap, the waiting threads will unblock and
1224  * extract those items.
1225  * @note 2. Calling std::swap on AsyncQueueDispatch objects is thread
1226  * safe but does not provide a thread-wise atomic swap (the swapped
1227  * objects may not be mirror images if during the execution of
1228  * std::swap's default algorithm one of them has been modified),
1229  * although in many cases that doesn't matter. If swap() is called
1230  * without a namespace qualifier, argument dependent look-up will pick
1231  * this one correctly.
1232  *
1233  * Since 2.0.8
1234  */
1235 template <class T, class Container>
1238  q1.swap(q2);
1239 }
1240 
1241 } // namespace Cgu
1242 
1243 #endif