docs/classtf_1_1AsyncTask.html
class to hold a dependent asynchronous task with shared ownership
A tf::AsyncTask is a lightweight handle that retains shared ownership of a dependent asynchronous (dependent-async) task created by an executor. This shared ownership ensures that the dependent-async task remains alive when adding it to the dependency list of another dependent-async task, thus avoiding the classical ABA problem.
// main thread retains shared ownership of async task Atf::AsyncTask A = executor.silent\_dependent\_async([](){});// task A remains alive (i.e., at least one ref count by the main thread) // when being added to the dependency list of async task Btf::AsyncTask B = executor.silent\_dependent\_async([](){}, A);
tf::AsyncTask is implemented based on the logic of C++ smart pointer std::shared_ptr and is considered cheap to copy or move as long as only a handful of objects own it. When a worker completes an async task, it will remove the task from the executor, decrementing the number of shared owners by one. If that counter reaches zero, the task is destroyed.
AsyncTask() defaultedconstructs an empty task handle~AsyncTask()destroys the managed dependent-async task if this is the last ownerAsyncTask(const AsyncTask& rhs)constructs a dependent-async task that shares ownership of rhsAsyncTask(AsyncTask&& rhs)move-constructs an dependent-async task from rhs
auto operator=(const AsyncTask& rhs) -> AsyncTask©-assigns the dependent-async task from rhsauto operator=(AsyncTask&& rhs) -> AsyncTask&move-assigns the dependent-async task from rhsauto empty() const -> boolchecks if this dependent-async task is associated with any taskvoid reset()release the managed object of thisauto hash_value() const -> size_tobtains the hashed value of this dependent-async taskauto use_count() const -> size_treturns the number of shared owners that are currently managing this dependent-async taskauto is_done() const -> boolchecks if this dependent-async task finishesauto exception_ptr() const -> std::exception_ptrretrieves the exception pointer of this taskauto has_exception_ptr() const -> boolqueries if the task has an exception pointer
copy-assigns the dependent-async task from rhs
Releases the managed object of this and retains a new shared ownership of rhs.
move-assigns the dependent-async task from rhs
Releases the managed object of this and takes over the ownership of rhs.
checks if this dependent-async task is associated with any task
An empty dependent-async task is not associated with any task created from the executor.
tf::AsyncTask task;assert(task.empty());
release the managed object of this
Releases the ownership of the managed task, if any. After the call *this manages no task.
tf::AsyncTask task = executor.silent\_dependent\_async([](){});assert(task.empty() == false);task.reset();assert(task.empty() == true);
obtains the hashed value of this dependent-async task
tf::AsyncTask task = executor.silent\_dependent\_async([](){});std::cout \<\< task.hash\_value() \<\< '\n';
returns the number of shared owners that are currently managing this dependent-async task
In a multithreaded environment, use_count atomically retrieves (with memory_order_relaxed load) the number of tf::AsyncTask instances that manage the current task.
tf::AsyncTask task;assert(task.use\_count() == 0);
checks if this dependent-async task finishes
In a multithreaded environment, is_done atomically retrieves (with memory_order_acquire load) the underlying state bit that indicates the completion of this dependent-async task. If the dependent-async task is empty, returns true.
tf::AsyncTask task = executor.silent\_dependent\_async([](){});while(task.is\_done() == false);std::cout \<\< "dependent-async task finishes\n";task.reset();assert(task.is\_done() == true);
retrieves the exception pointer of this task
This method retrieves the exception pointer of the task, if any, that was silently caught by the executor. For example, the code below retrieves the exception pointer of a dependent-async task that does not have a shared state to propagate its exception.
tf::AsyncTask task = executor.silent\_dependent\_async(&{throw std::runtime\_error("oops"); });executor.wait\_for\_all();// propagate the exception to the outer callerassert(task.exception\_ptr() != nullptr);std::rethrow\_exception(task.exception\_ptr());
queries if the task has an exception pointer
The method checks whether the task holds a pointer to a silently caught exception.