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