c++-gtk-utils
|
A thread-safe asynchronous queue with a blocking pop() method. More...
#include <c++-gtk-utils/async_queue.h>
Public Types | |
typedef Container::value_type | value_type |
typedef Container::size_type | size_type |
typedef Container | container_type |
Public Member Functions | |
void | push (const value_type &obj) |
void | pop (value_type &obj) |
void | pop_dispatch (value_type &obj) |
bool | pop_timed_dispatch (value_type &obj, unsigned int millisec) |
void | pop () |
bool | empty () const |
size_type | size () const |
void | swap (AsyncQueueDispatch &other) |
AsyncQueueDispatch & | operator= (const AsyncQueueDispatch &rhs) |
AsyncQueueDispatch () | |
AsyncQueueDispatch (const AsyncQueueDispatch &rhs) | |
~AsyncQueueDispatch () | |
A thread-safe asynchronous queue with a blocking pop() method.
AsyncQueueDispatch is similar to the AsyncQueue class, except that it has a blocking pop_dispatch() method, which allows it to be waited on by a dedicated event/message dispatching thread for incoming work (represented by the data pushed onto the queue). In the same way, it can be used to implement thread pools, by having threads in the pool waiting on the queue. The AsyncResult class can be useful for passing results between threads in conjunction with AsyncQueueDispatch (the documentation on AsyncResult gives an example).
By default the queue uses a std::list object as its container because when adding an item to the queue all allocation can take place outside the queue object's mutex. However, for types which have low overhead copy constructors, this can be changed to, say, a std::deque object by specifying it as the second template parameter.
If data pushed and popped from the queue are held by a reference counted smart pointer, the reference count must be thread-safe, such as by using SharedLockPtr or IntrusiveLockCounter.
If the library is installed using the --with-glib-memory-slices-compat or --with-glib-memory-slices-no-compat configuration options, any AsyncQueueDispatch objects constructed on free store will be constructed in glib memory slices. This does not affect the queue container itself: to change the allocator of the C++ container, a custom allocator type can be provided when the AsyncQueueDispatch object is instantiated offering the standard allocator interface. If glib memory slices are not used or no AsyncQueueDispatch objects are constructed on free store, it is not necessary to call g_thread_init() before manipulating or using an AsyncQueueDispatch object in multiple threads, but prior to glib version 2.32 glib itself (and thus glib memory slices) are not thread safe unless that function has been called.
typedef Container Cgu::AsyncQueueDispatch< T, Container >::container_type |
typedef Container::size_type Cgu::AsyncQueueDispatch< T, Container >::size_type |
typedef Container::value_type Cgu::AsyncQueueDispatch< T, Container >::value_type |
|
inline |
std::bad_alloc | The default constructor might throw this exception if memory is exhausted and the system throws in that case. |
Thread::MutexError | The default constructor might throw this exception if initialisation of the contained mutex fails. (It is often not worth checking for this, as it means either memory is exhausted or pthread has run out of other resources to create new mutexes.) |
Thread::CondError | The default constructor might throw this exception if initialisation of the contained condition variable fails. (It is often not worth checking for this, as it means either memory is exhausted or pthread has run out of other resources to create new condition variables.) |
|
inline |
The copy constructor is thread safe, as it locks the initializing object's mutex to obtain a consistent view of it.
rhs | The AsyncQueue object to be copied. |
std::bad_alloc | The copy constructor of the queue's container type, and so this constructor, might throw std::bad_alloc if memory is exhausted and the system throws in that case. It will also throw if the copy constructor of the queue's container type throws any other exceptions, including if any copy or move constructor or copy or move assignment operator of a contained item throws. |
Thread::MutexError | The copy constructor might throw Thread::MutexError if initialization of the contained mutex fails. (It is often not worth checking for this, as it means either memory is exhausted or pthread has run out of other resources to create new mutexes.) |
Thread::CondError | The copy constructor might throw this exception if initialisation of the contained condition variable fails. (It is often not worth checking for this, as it means either memory is exhausted or pthread has run out of other resources to create new condition variables.) |
Since 1.2.22
|
inline |
The destructor does not throw unless the destructor of a contained item throws. It is thread safe (any thread may delete the AsyncQueueDispatch object). Destroying an AsyncQueueDispatch object on which another thread is currently blocked results in undefined behavior.
|
inline |
|
inline |
The assignment operator is strongly exception safe with the standard sequence containers (it uses copy and swap). It is also thread safe, as it safely locks both the assignor's and assignee's mutex to provide a thread-wise atomic assignment.
rhs | The assignor. |
std::bad_alloc | The copy constructor of the queue's container type, and so this assignment operator, might throw std::bad_alloc if memory is exhausted and the system throws in that case. This assignment operator will also throw if the copy constructor of the queue's container type throws any other exceptions, including if any copy or move constructor or copy or move assignment operator of a contained item throws. |
Thread::MutexError | The assignment operator might throw Thread::MutexError if initialization of a transitional object's contained mutex fails. (It is often not worth checking for this, as it means either memory is exhausted or pthread has run out of other resources to create new mutexes.) |
Thread::CondError | The assignment operator might throw this exception if initialisation of a transitional object's contained condition variable fails. (It is often not worth checking for this, as it means either memory is exhausted or pthread has run out of other resources to create new condition variables.) |
Since 1.2.22
|
inline |
Discards the item at the front of the queue. This method has strong exception safety if the container is a std::deque or std::list container (the default is std::list), provided the destructor of a contained item does not throw. It is thread safe.
AsyncQueuePopError | If the queue is empty when a pop is attempted, this method will throw AsyncQueuePopError. It might also throw if the destructor of the queue item might throw (but that should never happen), or if the empty() method of the container type throws (which would not happen on any sane implementation). |
|
inline |
Pops an item from the queue. This method has strong exception safety if the container is a std::deque or std::list container (the default is std::list), provided the destructor of a contained item does not throw. It is thread safe.
obj | A value type reference to which the item at the front of the queue will be assigned. |
AsyncQueuePopError | If the queue is empty when a pop is attempted, this method will throw AsyncQueuePopError. It might also throw if the assignment operator of the queue item might throw. In order to complete pop() operations atomically under a single lock and to retain strong exception safety, the object into which the pop()ed data is to be placed is passed as an argument by reference (this avoids a copy from a temporary object after the data has been extracted from the queue, which would occur if the item extracted were returned by value). It might also throw if the destructor of the queue item might throw (but that should never happen), or if the empty() method of the container type throws (which would not happen on any sane implementation). |
|
inline |
Pops an item from the queue. If the queue is empty, it will block until an item becomes available. If it blocks, the wait comprises a cancellation point. This method is cancellation safe if the stack unwinds on cancellation, as cancellation is blocked while the queue is being operated on after coming out of a wait. This method has strong exception safety if the container is a std::deque or std::list container (the default is std::list), provided the destructor of a contained item does not throw. It is thread safe.
obj | A value type reference to which the item at the front of the queue will be assigned. This method might throw if the assignment operator of the queue item might throw. In order to complete pop() operations atomically under a single lock and to retain strong exception safety, the object into which the pop()ed data is to be placed is passed as an argument by reference (this avoids a copy from a temporary object after the data has been extracted from the queue, which would occur if the item extracted were returned by value). It might also throw if the destructor of the queue item might throw (but that should never happen), or if the empty() method of the container type throws (which would not happen on any sane implementation). |
|
inline |
Pops an item from the queue. If the queue is empty, it will block until an item becomes available or until the timeout expires. If it blocks, the wait comprises a cancellation point. This method is cancellation safe if the stack unwinds on cancellation, as cancellation is blocked while the queue is being operated on after coming out of a wait. This method has strong exception safety if the container is a std::deque or std::list container (the default is std::list), provided the destructor of a contained item does not throw. It is thread safe.
obj | A value type reference to which the item at the front of the queue will be assigned. This method might throw if the assignment operator of the queue item might throw. In order to complete pop() operations atomically under a single lock and to retain strong exception safety, the object into which the pop()ed data is to be placed is passed as an argument by reference (this avoids a copy from a temporary object after the data has been extracted from the queue, which would occur if the item extracted were returned by value). It might also throw if the destructor of the queue item might throw (but that should never happen), or if the empty() method of the container type throws (which would not happen on any sane implementation). |
millisec | The timeout interval, in milliseconds. |
|
inline |
Pushes an item onto the queue. This method has strong exception safety if the container is a std::list or std::deque container (the default is std::list), except that if std::deque is used as the container under C++11 and the copy constructor, move constructor, assignment operator or move assignment operator of the queue item throws, it only gives the basic exception guarantee (and the basic guarantee is not given by std::deque under C++11 if the queue item's move constructor throws and it uses a non-default allocator which does not provide for it to be CopyInsertable). It is thread safe.
obj | The item to be pushed onto the queue. |
std::bad_alloc | The method might throw std::bad_alloc if memory is exhausted and the system throws in that case. It might also throw if the copy constructor or assignment operator of the queue item might throw (or under C++11 if its move constructor or move assignment operator throws). |
|
inline |
Since 1.2.22
|
inline |
Swaps the contents of 'this' and 'other'. It will not throw assuming that the swap method of the container type does not throw (which the C++ standard requires not to happen with the standard sequence containers). It is thread safe and the swap is thread-wise atomic. A non-class function Cgu::swap(Cgu::AsyncQueueDispatch&, Cgu::AsyncQueueDispatch&) method is also provided which will call this method.
other | The object to be swapped with this one. |
Since 1.2.22