C/C++ API Reference
Loading...
Searching...
No Matches
fallible_coro_task.h
1// Copyright 2023 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 <concepts>
17
18#include "pw_async2/coro.h"
19#include "pw_async2/func_task.h"
20#include "pw_function/function.h"
21
22namespace pw::async2 {
23
25
28template <typename T,
29 typename AllocationErrorHandler = pw::Function<void()>,
30 ReturnValuePolicy policy = std::is_void_v<T>
31 ? ReturnValuePolicy::kDiscard
32 : ReturnValuePolicy::kKeep>
33 requires std::invocable<AllocationErrorHandler>
34class FallibleCoroTask final : public Task {
35 public:
36 using value_type = std::conditional_t<std::is_void_v<T>, ReadyType, T>;
37
40 template <typename ErrorHandler>
41 FallibleCoroTask(Coro<T>&& coro, ErrorHandler&& error_handler)
42 : Task(PW_ASYNC_TASK_NAME("FallibleCoroTask<T>")),
43 coro_(std::move(coro)),
44 error_handler_(std::forward<ErrorHandler>(error_handler)) {}
45
46 FallibleCoroTask(const FallibleCoroTask&) = delete;
47 FallibleCoroTask& operator=(const FallibleCoroTask&) = delete;
49 FallibleCoroTask& operator=(FallibleCoroTask&&) = delete;
50
51 ~FallibleCoroTask() override { Deregister(); }
52
57 [[nodiscard]] bool ok() const { return coro_.ok(); }
58
61 bool has_value() const { return return_value_.has_value(); }
62
66 value_type& value() { return return_value_.value(); }
67
69 const value_type& value() const { return return_value_.value(); }
70
74 std::optional<value_type>& Wait() {
75 Task::Join();
76 return return_value_;
77 }
78
79 private:
80 Poll<> DoPend(Context& cx) final {
81 if (!coro_.ok()) {
82 error_handler_();
83 return Ready();
84 }
85
86 auto result = coro_.Pend(cx);
87 switch (result.state()) {
88 case internal::CoroPollState::kPending:
89 return Pending();
90 case internal::CoroPollState::kAborted:
91 error_handler_();
92 return Ready();
93 case internal::CoroPollState::kReady:
94 return_value_ = std::move(*result);
95 return Ready();
96 }
97 }
98
99 Coro<T> coro_;
100 AllocationErrorHandler error_handler_;
101 std::optional<T> return_value_;
102};
103
106template <typename T, typename AllocationErrorHandler>
107class FallibleCoroTask<T, AllocationErrorHandler, ReturnValuePolicy::kDiscard>
108 final : public Task {
109 public:
110 FallibleCoroTask(Coro<T>&& coro, AllocationErrorHandler&& error_handler)
111 : Task(PW_ASYNC_TASK_NAME("FallibleCoroTask")),
112 coro_(std::move(coro)),
113 error_handler_(std::move(error_handler)) {}
114
115 FallibleCoroTask(const FallibleCoroTask&) = delete;
116 FallibleCoroTask& operator=(const FallibleCoroTask&) = delete;
118 FallibleCoroTask& operator=(FallibleCoroTask&&) = delete;
119
120 ~FallibleCoroTask() override { Deregister(); }
121
126 [[nodiscard]] bool ok() const { return coro_.ok(); }
127
128 private:
129 Poll<> DoPend(Context& cx) final {
130 if (!coro_.ok()) {
131 error_handler_();
132 return Ready();
133 }
134 switch (coro_.Pend(cx).state()) {
135 case internal::CoroPollState::kPending:
136 return Pending();
137 case internal::CoroPollState::kAborted:
138 error_handler_();
139 return Ready();
140 case internal::CoroPollState::kReady:
141 return Ready();
142 }
143 }
144
145 Coro<T> coro_;
146 AllocationErrorHandler error_handler_;
147};
148
149template <typename T, typename AllocationErrorHandler>
150FallibleCoroTask(Coro<T>&&, AllocationErrorHandler&&)
151 -> FallibleCoroTask<T, std::decay_t<AllocationErrorHandler>>;
152
154
155} // namespace pw::async2
Definition: context.h:46
Definition: coro.h:546
Poll DoPend(Context &cx) final
Definition: fallible_coro_task.h:129
Definition: fallible_coro_task.h:34
std::optional< value_type > & Wait()
Definition: fallible_coro_task.h:74
Poll DoPend(Context &cx) final
Definition: fallible_coro_task.h:80
const value_type & value() const
Definition: fallible_coro_task.h:69
FallibleCoroTask(Coro< T > &&coro, ErrorHandler &&error_handler)
Definition: fallible_coro_task.h:41
bool ok() const
Definition: fallible_coro_task.h:57
bool has_value() const
Definition: fallible_coro_task.h:61
value_type & value()
Definition: fallible_coro_task.h:66
Definition: poll.h:138
Definition: task.h:78
constexpr PendingType Pending()
Returns a value indicating that an operation was not yet able to complete.
Definition: poll.h:353
constexpr Poll Ready()
Returns a value indicating completion.
Definition: poll.h:337
ReturnValuePolicy
Whether to store or discard the function's return value in RunOnceTask.
Definition: func_task.h:62
#define PW_ASYNC_TASK_NAME(name)
Generates a token for use as a task name.
Definition: task.h:32
fit::function_impl< function_internal::config::kInlineCallableSize, !function_internal::config::kEnableDynamicAllocation, FunctionType, PW_FUNCTION_DEFAULT_ALLOCATOR_TYPE > Function
Definition: function.h:73
Definition: poll.h:40