Pigweed
C/C++ API Reference
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
task.h
1// Copyright 2025 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14#pragma once
15
16#include "pw_async2/context.h"
17#include "pw_async2/lock.h"
18#include "pw_async2/poll.h"
19#include "pw_containers/intrusive_forward_list.h"
20#include "pw_containers/intrusive_list.h"
21#include "pw_log/tokenized_args.h"
22#include "pw_sync/lock_annotations.h"
23
24namespace pw::async2 {
25
27#define PW_ASYNC_TASK_NAME(name) PW_LOG_TOKEN_EXPR("pw_async2", name)
28
29class NativeDispatcherBase;
30
61class Task : public IntrusiveList<Task>::Item {
62 friend class Dispatcher;
63 friend class Waker;
64 friend class NativeDispatcherBase;
65
66 public:
67 Task() = default;
68
77 constexpr Task(log::Token name) : name_(name) {}
78
79 Task(const Task&) = delete;
80 Task(Task&&) = delete;
81 Task& operator=(const Task&) = delete;
82 Task& operator=(Task&&) = delete;
83
84 virtual ~Task() {
85 // Note: the task must not be registered with a ``Dispatcher` upon
86 // destruction. This happens automatically upon ``Task`` completion or upon
87 // ``Dispatcher`` destruction.
88 //
89 // This is necessary to ensure that neither the ``Dispatcher`` nor
90 // ``Waker`` reference the ``Task`` object after destruction.
91 //
92 // Note that the ``~Task`` destructor cannot perform this deregistration,
93 // as there is no guarantee that (1) the task is not being actively polled
94 // and (2) by the time the ``~Task`` destructor is reached, the subclass
95 // destructor has already run, invalidating the subclass state that may be
96 // read by the ``Pend`` implementation.
97 }
98
108 Poll<> Pend(Context& cx) { return DoPend(cx); }
109
118 bool IsRegistered() const;
119
135
142 void Destroy() { DoDestroy(); }
143
144 private:
149 bool TryDeregister() PW_EXCLUSIVE_LOCKS_REQUIRED(impl::dispatcher_lock());
150
168 virtual Poll<> DoPend(Context&) = 0;
169
177 virtual void DoDestroy() {}
178
179 // Unlinks all ``Waker`` objects associated with this ``Task.``
180 void RemoveAllWakersLocked()
181 PW_EXCLUSIVE_LOCKS_REQUIRED(impl::dispatcher_lock());
182
183 // Adds a ``Waker`` to the linked list of ``Waker`` s tracked by this
184 // ``Task``.
185 void AddWakerLocked(Waker&)
186 PW_EXCLUSIVE_LOCKS_REQUIRED(impl::dispatcher_lock());
187
188 // Removes a ``Waker`` from the linked list of ``Waker`` s tracked by this
189 // ``Task``
190 //
191 // Precondition: the provided waker *must* be in the list of ``Waker`` s
192 // tracked by this ``Task``.
193 void RemoveWakerLocked(Waker&)
194 PW_EXCLUSIVE_LOCKS_REQUIRED(impl::dispatcher_lock());
195
196 enum class State {
197 kUnposted,
198 kRunning,
199 kWoken,
200 kSleeping,
201 };
202
203 // The current state of the task.
204 State state_ PW_GUARDED_BY(impl::dispatcher_lock()) = State::kUnposted;
205
206 // A pointer to the dispatcher this task is associated with.
207 //
208 // This will be non-null when `state_` is anything other than `kUnposted`.
209 //
210 // This value must be cleared by the dispatcher upon destruction in order to
211 // prevent null access.
212 NativeDispatcherBase* dispatcher_ PW_GUARDED_BY(impl::dispatcher_lock()) =
213 nullptr;
214
215 // Linked list of ``Waker`` s that may awaken this ``Task``.
216 IntrusiveForwardList<Waker> wakers_ PW_GUARDED_BY(impl::dispatcher_lock());
217
218 // Optional user-facing name for the task. If set, it will be included in
219 // debug logs.
220 log::Token name_ = log::kDefaultToken;
221};
222
223} // namespace pw::async2
Definition: intrusive_forward_list.h:86
Definition: context.h:53
A single-threaded cooperatively-scheduled runtime for async tasks.
Definition: dispatcher.h:46
Definition: dispatcher_base.h:47
Definition: poll.h:54
Definition: task.h:61
void Destroy()
Definition: task.h:142
virtual Poll DoPend(Context &)=0
constexpr Task(log::Token name)
Definition: task.h:77
Poll Pend(Context &cx)
Definition: task.h:108
bool IsRegistered() const
virtual void DoDestroy()
Definition: task.h:177
Definition: waker.h:154
Definition: intrusive_list.h:82