Pigweed
C/C++ API Reference
|
Public Member Functions | |
constexpr | Task (log::Token name) |
Task (const Task &)=delete | |
Task (Task &&)=delete | |
Task & | operator= (const Task &)=delete |
Task & | operator= (Task &&)=delete |
Poll | Pend (Context &cx) |
bool | IsRegistered () const |
void | Deregister () |
void | Destroy () |
Private Member Functions | |
virtual Poll | DoPend (Context &)=0 |
virtual void | DoDestroy () |
Friends | |
class | Dispatcher |
class | Waker |
class | NativeDispatcherBase |
Additional Inherited Members | |
![]() | |
constexpr | Item ()=default |
A task which may complete one or more asynchronous operations.
The Task
interface is commonly implemented by users wishing to schedule work on an asynchronous Dispatcher
. To do this, users may subclass Task
, providing an implementation of the DoPend
method which advances the state of the Task
as far as possible before yielding back to the Dispatcher
.
This process works similarly to cooperatively-scheduled green threads or coroutines, with a Task
representing a single logical "thread" of execution. Unlike some green thread or coroutine implementations, Task
does not imply a separately-allocated stack: Task
state is most commonly stored in fields of the Task
subclass.
Once defined by a user, Task
s may be run by passing them to a Dispatcher
via Dispatcher::Post
. The Dispatcher
will then Pend
the Task
every time that the Task
indicates it is able to make progress.
Note that Task
objects must not be destroyed while they are actively being Pend
'd by a Dispatcher
. To protect against this, be sure to do one of the following:
Task
objects that continue to live until they receive a DoDestroy
call.Task
objects whose stack-based lifetimes outlive their associated Dispatcher
.Deregister
on the Task
prior to its destruction. NOTE that Deregister
may not be called from inside the Task
's own Pend
method.
|
inlineconstexpr |
Creates a task with the specified name. To generate a name token, use the PW_ASYNC_TASK_NAME
macro, e.g.
void pw::async2::Task::Deregister | ( | ) |
Deregisters this Task
from the linked Dispatcher
and any associated Waker
values.
This must not be invoked from inside this task's Pend
function, as this will result in a deadlock.
NOTE: If this task's Pend
method is currently being run on the dispatcher, this method will block until Pend
completes.
NOTE: This method sadly cannot guard against the dispatcher itself being destroyed, so this method must not be called concurrently with destruction of the dispatcher associated with this Task
.
Note that this will not destroy the underlying Task
.
|
inline |
A public interface for DoDestroy
.
DoDestroy
is normally invoked by a Dispatcher
after a Post
ed Task
has completed.
This should only be called by Task
s delegating to other Task
s.
|
inlineprivatevirtual |
Performs any necessary cleanup of Task
memory after completion.
This may include calls to std::destroy_at(this)
, and may involve deallocating the memory for this Task
itself.
Tasks implementations which wish to be reused may skip self-destruction here.
Reimplemented in pw::async2::internal::AllocatedTask< Pendable >, and pw::async2::internal::RunHeapFuncTask< Func >.
Attempts to advance this Task
to completion.
This method should not perform synchronous waiting, as doing so may block the main Dispatcher
loop and prevent other Task
s from progressing. Because of this, Task
s should not invoke blocking Dispatcher
methods such as RunUntilComplete
.
Task
s should also avoid invoking RunUntilStalled` on their own
Dispatcher``.
Returns Ready
if complete, or Pending
if the Task
was not yet able to complete.
If Pending
is returned, the Task
must ensure it is woken up when it is able to make progress. To do this, Task::Pend
must arrange for Waker::Wake
to be called, either by storing a copy of the Waker
away to be awoken by another system (such as an interrupt handler).
Implemented in pw::async2::internal::RunHeapFuncTask< Func >, pw::async2::internal::AllocatedTask< Pendable >, pw::async2::CoroOrElseTask, pw::async2::internal::PendableAsTaskWithOutput< Pendable >, pw::async2::PendFuncTask< Func >, and pw::async2::PendableAsTask< Pendable >.
bool pw::async2::Task::IsRegistered | ( | ) | const |
Whether or not the Task
is registered with a Dispatcher
.
Returns true
after this Task
is passed to Dispatcher::Post
until one of the following occurs:
Task
returns Ready
from its Pend
method.Task::Deregister
is called.Dispatcher
is destroyed. A public interface for DoPend
.
DoPend
is normally invoked by a Dispatcher
after a Task
has been Post
ed.
This wrapper should only be called by Task
s delegating to other Task
s. For example, a class MainTask
might have separate fields for TaskA
and TaskB
, and could invoke Pend
on these types within its own DoPend
implementation.