C/C++ API Reference
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
29#define PW_ASYNC_TASK_NAME(name) PW_LOG_TOKEN_EXPR("pw_async2", name)
30
31class NativeDispatcherBase;
32
63class Task : public IntrusiveList<Task>::Item {
64 friend class Dispatcher;
65 friend class Waker;
66 friend class NativeDispatcherBase;
67
68 public:
69 Task() = default;
70
79 constexpr Task(log::Token name) : name_(name) {}
80
81 Task(const Task&) = delete;
82 Task(Task&&) = delete;
83 Task& operator=(const Task&) = delete;
84 Task& operator=(Task&&) = delete;
85
86 virtual ~Task() {
87 // Note: the task must not be registered with a ``Dispatcher` upon
88 // destruction. This happens automatically upon ``Task`` completion or upon
89 // ``Dispatcher`` destruction.
90 //
91 // This is necessary to ensure that neither the ``Dispatcher`` nor
92 // ``Waker`` reference the ``Task`` object after destruction.
93 //
94 // Note that the ``~Task`` destructor cannot perform this deregistration,
95 // as there is no guarantee that (1) the task is not being actively polled
96 // and (2) by the time the ``~Task`` destructor is reached, the subclass
97 // destructor has already run, invalidating the subclass state that may be
98 // read by the ``Pend`` implementation.
99 }
100
110 Poll<> Pend(Context& cx) { return DoPend(cx); }
111
120 bool IsRegistered() const;
121
137
144 void Destroy() { DoDestroy(); }
145
146 private:
151 bool TryDeregister() PW_EXCLUSIVE_LOCKS_REQUIRED(impl::dispatcher_lock());
152
170 virtual Poll<> DoPend(Context&) = 0;
171
179 virtual void DoDestroy() {}
180
181 // Unlinks all ``Waker`` objects associated with this ``Task.``
182 void RemoveAllWakersLocked()
183 PW_EXCLUSIVE_LOCKS_REQUIRED(impl::dispatcher_lock());
184
185 // Adds a ``Waker`` to the linked list of ``Waker`` s tracked by this
186 // ``Task``.
187 void AddWakerLocked(Waker&)
188 PW_EXCLUSIVE_LOCKS_REQUIRED(impl::dispatcher_lock());
189
190 // Removes a ``Waker`` from the linked list of ``Waker`` s tracked by this
191 // ``Task``
192 //
193 // Precondition: the provided waker *must* be in the list of ``Waker`` s
194 // tracked by this ``Task``.
195 void RemoveWakerLocked(Waker&)
196 PW_EXCLUSIVE_LOCKS_REQUIRED(impl::dispatcher_lock());
197
198 enum class State {
199 kUnposted,
200 kRunning,
201 kWoken,
202 kSleeping,
203 };
204
205 // The current state of the task.
206 State state_ PW_GUARDED_BY(impl::dispatcher_lock()) = State::kUnposted;
207
208 // A pointer to the dispatcher this task is associated with.
209 //
210 // This will be non-null when `state_` is anything other than `kUnposted`.
211 //
212 // This value must be cleared by the dispatcher upon destruction in order to
213 // prevent null access.
214 NativeDispatcherBase* dispatcher_ PW_GUARDED_BY(impl::dispatcher_lock()) =
215 nullptr;
216
217 // Linked list of ``Waker`` s that may awaken this ``Task``.
219
220 // Optional user-facing name for the task. If set, it will be included in
221 // debug logs.
223};
224
226
227} // namespace pw::async2
Definition: intrusive_forward_list.h:91
Definition: context.h:55
A single-threaded cooperatively scheduled runtime for async tasks.
Definition: dispatcher.h:48
Definition: dispatcher_base.h:49
Definition: poll.h:60
Definition: task.h:63
void Destroy()
Definition: task.h:144
virtual Poll DoPend(Context &)=0
constexpr Task(log::Token name)
Definition: task.h:79
Poll Pend(Context &cx)
Definition: task.h:110
bool IsRegistered() const
virtual void DoDestroy()
Definition: task.h:179
Definition: waker.h:160
Definition: intrusive_list.h:88
pw::sync::InterruptSpinLock & dispatcher_lock()
Definition: lock.h:33
#define PW_GUARDED_BY(x)
Definition: lock_annotations.h:60
#define PW_EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: lock_annotations.h:146
constexpr Token kDefaultToken
Default value of a log token. This token should not be logged.
Definition: tokenized_args.h:102
const char * Token
Definition: tokenized_args.h:99