c++-gtk-utils
|
A thread-safe asynchronous result class. More...
#include <c++-gtk-utils/async_result.h>
Public Member Functions | |
AsyncResult () | |
~AsyncResult () | |
AsyncResult (const AsyncResult &)=delete | |
AsyncResult & | operator= (const AsyncResult &)=delete |
bool | set (const T &val) |
bool | set (T &&val) |
T | get () const |
T | move_get () |
bool | set_error (int err=-1) |
int | get_error () const |
bool | is_done () const |
A thread-safe asynchronous result class.
Cgu::Thread::Future operates on the principle of there being one worker thread per task. In some cases however, it may be better to have a worker thread, or a limited pool of worker threads, executing a larger number of tasks. This can be implemented by having a worker thread or threads waiting on a Cgu::AsyncQueueDispatch object, onto which other threads push tasks represented by std::unique_ptr<const Cgu::Callback::Callback> or Cgu::Callback::SafeFunctor objects.
Where this model is adopted, when a task completes it may report its results by dispatching a further callback to a glib main loop using Cgu::Callback::post(). However, there will also be cases where, rather than passing a result as an event to a main loop, a thread is to to wait for the task to complete. This class is intended to facilitate that. It operates in a way which is similar to the std::promise class in C++11. The thread which wishes to extract a result can call the get() method, which will block until the worker thread has called the set() method or posted an error.
For safety reasons, the get() method returns by value and so will cause that value to be copied once. From version 2.0.11 a move_get() method is provided which will make a move operation instead of a copy if the value type implements a move constructor, but see the documentation on move_get() for the caveats with respect to its use: in particular, if move_get() is to be called by a thread, then get() may not be called by another thread.
Here is a compilable example of a calculator class which runs a dedicated thread on which it carries out all its calculations:
AsyncResult objects cannot be copied by value, and as they need to be visible both to the set()ing and get()ing threads, it will often be easiest to construct them on free store and copy them by smart pointer, as in the example above. However, if the library is compiled with the --with-glib-memory-slices-compat or --with-glib-memory-slices-no-compat configuration options, any AsyncResult object constructed on free store will be constructed in glib memory slices, which are an efficient small object allocator.
|
inline |
Thread::MutexError | The 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.) The constructor will also throw if the default constructor of the result type represented by this object throws. |
Thread::CondError | The 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.) The constructor will also throw if the default constructor of the result type represented by this object throws. |
Since 2.0.8
|
inline |
|
delete |
This class cannot be copied. The copy constructor is deleted.
Since 2.0.8
|
inline |
This method gets the stored value represented by the AsyncResult object. It is thread safe. It is a cancellation point if it blocks, and is cancellation safe if the stack unwinds on cancellation. Any number of threads may call this method and block on it. It will not throw unless the copy constructor of the return type throws. It is strongly exception safe.
Since 2.0.8
|
inline |
This method is thread safe. It is not a cancellation point. It will not throw.
Since 2.0.8
|
inline |
This method is thread safe. It is not a cancellation point. It will not throw.
Since 2.0.8
|
inline |
This method gets the stored value represented by the AsyncResult object by a move operation, if the type of that value implements a move constructor (otherwise this method does the same as the get() method). It is provided as an option for cases where a move is required for efficiency reasons, but although it may be called by any thread, a move operation may normally only be made once (except where the return type has been designed to be moved more than once for the limited purpose of inspecting a flag indicating whether its value is valid or not). If this method is to be called then no calls to get() by another thread should normally be made. This method is a cancellation point if it blocks, and is cancellation safe if the stack unwinds on cancellation. It will not throw unless the copy or move constructor of the return type throws. It is only exception safe if the return type's move constructor is exception safe.
Since 2.0.11
|
delete |
This class cannot be copied. The assignment operator is deleted.
Since 2.0.8
|
inline |
This method sets the value represented by the AsyncResult object, provided that set() has not previously been called and set_error() has not previously been called with a value other than 0. If set() has previously been called or set_error() called with a value other than 0 (so that is_done() will return true) this method does nothing. It is thread safe. It is not a cancellation point. It will not throw unless the copy assignment operator of the value type throws.
val | The value which this object is to represent and which calls to get() or a call to move_get() will return. Any thread waiting on get() or move_get() will unblock, and any subsequent calls to is_done() will return true. |
Since 2.0.8
|
inline |
This method sets the value represented by the AsyncResult object, provided that set() has not previously been called and set_error() has not previously been called with a value other than 0. If set() has previously been called or set_error() called with a value other than 0 (so that is_done() will return true) this method does nothing. It is thread safe. It is not a cancellation point. It will not throw unless the copy or move assignment operator of the value type throws.
val | The value which this object is to represent and which calls to get() or a call to move_get() will return. Any thread waiting on get() or move_get() will unblock, and any subsequent calls to is_done() will return true. |
Since 2.0.8
|
inline |
This method sets an error if called with a value other than 0, provided that set() has not previously been called and this method has not previously been called with a value other than 0. If set() has been called or this method previously called with a value other than 0 (so that is_done() will return true), this method does nothing. This method is thread safe. It is not a cancellation point. It will not throw.
err | The value which subsequent calls to get_error() will report. If the value of err is 0, or if this method has been called with a value other than 0 or set() has previously been called, this method will do nothing. Otherwise, any thread waiting on get() or move_get() will unblock (they will return a default constructed object of the template type), and any subsequent calls to is_done() will return true. |
Since 2.0.8