Class task_group

Class Documentation

class concore::v1::task_group

Used to control a group of tasks (cancellation, waiting, exceptions).

Tasks can point to one task_group object. A task_group object can point to a parent task_group object, thus creating hierarchies of task_group objects.

task_group implements shared-copy semantics. If one makes a copy of a task_group object, the actual value of the task_group will be shared. For example, if we cancel one task_group, the second task_group is also canceled. concore takes advantage of this type of semantics and takes all task_group objects by copy, while the content is shared.

Scenario 1: cancellation User can tell a task_group object to cancel the tasks. After this, any tasks that use this task_group object will not be executed anymore. Tasks that are in progress at the moment of cancellation are not by default canceled. Instead, they can check from time to time whether the task is canceled.

If a parent task_group is canceled, all the tasks belonging to the children task_group objects are canceled.

Scenario 2: waiting for tasks A task_group object can be queried to check if all the tasks in a task_group are done executing. Actually, we are checking whether they are still active (the distinction is small, but can be important in some cases). Whenever all the tasks are done executing (they don’t reference the task_group anymore) then the task_group object can tell that. One can easily query this property by calling is_active()

Also, one can spawn a certain number of tasks, associating a task_group object with them and wait for all these tasks to be completed by waiting on the task_group object. This is an active wait: the thread tries to execute tasks while waiting (with the idea that it will try to speed up the completion of the tasks) the waiting algorithm can vary based on other factors.

Scenario 3: Exception handling One can set an exception handler to the task_group. If a task throws an exception, and the associated task_group has a handler set, then the handler will be called. This can be useful to keep track of exceptions thrown by tasks. For example, one might want to add logging for thrown exceptions.

See

task

Public Functions

task_group()

Default constructor.

Creates an empty, invalid task_group. No operations can be called on it. This is used to mark the absence of a real task_group.

See

create()

~task_group()

Destructor.

task_group(const task_group&) = default

Copy constructor.

Creates a shared-copy of this object. The new object and the old one will share the same implementation data.

task_group(task_group&&) = default

Move constructor; rarely used.

task_group &operator=(const task_group&) = default

Assignment operator.

Creates a shared-copy of this object. The new object and the old one will share the same implementation data.

Return

The result of the assignment

task_group &operator=(task_group&&) = default

Move assignment; rarely used.

operator bool() const

Checks if this is a valid task group object.

Returns true if this object was created by create() or if it’s a copy of an object created by calling create().

Such an object is valid, and operations can be made on it. Tasks will register into it and they can be influenced by the task_group object.

An object for which this returns false is considered invalid. It indicates the absence of a real task_group object.

See

create(), task_group()

void set_exception_handler(except_fun_t except_fun)

Set the function to be called whenever an exception is thrown by a task.

On execution, tasks can throw exceptions. If tasks have an associated

task_group, one can use this function to register an exception handler that will be called for exceptions.
Parameters
  • except_fun: The function to be called on exceptions

The given exception function will be called each time a new exception is thrown by a task belonging to this task_group object.

void cancel()

Cancels the execution tasks in the group.

All tasks from this task group scheduled for execution that are not yet started are canceled they won’t be executed anymore. If there are tasks of this group that are in execution, they can continue execution until the end. However, they have ways to check if the task group is canceled, so that they can stop prematurely.

Tasks that are added to the group after the group was canceled will be not executed.

To get rid of the cancellation, one can cal clear_cancel().

See

clear_cancel(), is_cancelled()

void clear_cancel()

Clears the cancel flag; new tasks can be executed again.

This reverts the effect of calling cancel(). Tasks belonging to this group can be executed once more after clear_clance() is called.

Note, once individual tasks were decided that are canceled and not executed, this clear_cancel() cannot revert that. Those tasks will be forever not-executed.

See

cancel(), is_cancelled()

bool is_cancelled() const

Checks if the tasks overseen by this object are canceled.

This will return

true after cancel() is called, and false if clear_cancel() is called. If this return true it means that tasks belonging to this group will not be executed.
Return

True if the task group is canceled, False otherwise.

cancel(), clear_cancel()

bool is_active() const

Checks whether there are active tasks in this group.

Creating one task into the task group will make the task group active, regardless of whether the task is executed or not. The group will become non-active whenever all the tasks created in the group are destroyed.

Return

True if active, False otherwise.

One main assumption of task_groups is that, if a task is created in a task_group, then it is somehow on the path to execution (i.e., enqueued in some sort of executor).

This can be used to check when all tasks from a group are completed.

If a group has sub-groups which have active tasks, this will return true.

See

task

Public Static Functions

task_group create(const task_group &parent = {})

Creates a task_group object, with an optional parent.

As opposed to a default constructor, this creates a valid

task_group object. Operations (canceling, waiting) can be performed on objects created by this function.
Return

The task group created.

Parameters
  • parent: The parent of the task_group object (optional)

The optional parent parameter allows one to create hierarchies of task_group objects. A hierarchy can be useful, for example, for canceling multiple groups of tasks all at once.

See

task_group()

task_group current_task_group()

Returns the task_group object for the current running task.

If there is no task running, this will return an empty (i.e., default-constructed) object. If there is a running task on this thread, it will return the

task_group object for the currently running task.
Return

The task group associated with the current running task

The intent of this function is to be called from within running tasks.

This uses thread-local-storage to store the task_group of the current running task.

See

is_current_task_cancelled(), task_group()

bool is_current_task_cancelled()

Determines if current task cancelled.

This should be called from within tasks to check if the

task_group associated with the current running task was cancelled.
Return

True if current task cancelled, False otherwise.

The intent of this function is to be called from within running tasks.

See

current_task_group()

task_group set_current_task_group(const task_group &grp)

Sets the task group for the current worker.

This is used by implementation of certain algorithms to speed up the use of task groups. Not intended to be heavily used. To be used with care.

Return

The previous set task group (if any).

Parameters
  • grp: The new group to be set for the current worker.

In general, after setting a task group, one may want to restore the old task group. This is why the function returns the previous task_group object.