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:
77 constexpr Task(log::Token name = kDefaultName) : 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:
145 static constexpr log::Token kDefaultName =
146 PW_LOG_TOKEN("pw_async2", "(anonymous)");
147
152 bool TryDeregister() PW_EXCLUSIVE_LOCKS_REQUIRED(impl::dispatcher_lock());
153
171 virtual Poll<> DoPend(Context&) = 0;
172
180 virtual void DoDestroy() {}
181
182 // Unlinks all ``Waker`` objects associated with this ``Task.``
183 void RemoveAllWakersLocked()
184 PW_EXCLUSIVE_LOCKS_REQUIRED(impl::dispatcher_lock());
185
186 // Adds a ``Waker`` to the linked list of ``Waker`` s tracked by this
187 // ``Task``.
188 void AddWakerLocked(Waker&)
189 PW_EXCLUSIVE_LOCKS_REQUIRED(impl::dispatcher_lock());
190
191 // Removes a ``Waker`` from the linked list of ``Waker`` s tracked by this
192 // ``Task``
193 //
194 // Precondition: the provided waker *must* be in the list of ``Waker`` s
195 // tracked by this ``Task``.
196 void RemoveWakerLocked(Waker&)
197 PW_EXCLUSIVE_LOCKS_REQUIRED(impl::dispatcher_lock());
198
199 enum class State {
200 kUnposted,
201 kRunning,
202 kWoken,
203 kSleeping,
204 };
205
206 // The current state of the task.
207 State state_ PW_GUARDED_BY(impl::dispatcher_lock()) = State::kUnposted;
208
209 // A pointer to the dispatcher this task is associated with.
210 //
211 // This will be non-null when `state_` is anything other than `kUnposted`.
212 //
213 // This value must be cleared by the dispatcher upon destruction in order to
214 // prevent null access.
215 NativeDispatcherBase* dispatcher_ PW_GUARDED_BY(impl::dispatcher_lock()) =
216 nullptr;
217
218 // Linked list of ``Waker`` s that may awaken this ``Task``.
220
221 // Optional user-facing name for the task. If set, it will be included in
222 // debug logs.
223 log::Token name_;
224};
225
227
228} // 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:142
virtual Poll DoPend(Context &)=0
Poll Pend(Context &cx)
Definition: task.h:108
bool IsRegistered() const
constexpr Task(log::Token name=kDefaultName)
Definition: task.h:77
virtual void DoDestroy()
Definition: task.h:180
Definition: waker.h:160
Definition: intrusive_list.h:88
pw::sync::InterruptSpinLock & dispatcher_lock()
Definition: lock.h:33
#define PW_LOG_TOKEN(...)
Definition: tokenized_args.h:63
#define PW_GUARDED_BY(x)
Definition: lock_annotations.h:60
#define PW_EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: lock_annotations.h:146