Mercurial > repos > rliterman > csp2
comparison CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/include/kj/async-prelude.h @ 69:33d812a61356
planemo upload commit 2e9511a184a1ca667c7be0c6321a36dc4e3d116d
author | jpayne |
---|---|
date | Tue, 18 Mar 2025 17:55:14 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
67:0e9998148a16 | 69:33d812a61356 |
---|---|
1 // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors | |
2 // Licensed under the MIT License: | |
3 // | |
4 // Permission is hereby granted, free of charge, to any person obtaining a copy | |
5 // of this software and associated documentation files (the "Software"), to deal | |
6 // in the Software without restriction, including without limitation the rights | |
7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
8 // copies of the Software, and to permit persons to whom the Software is | |
9 // furnished to do so, subject to the following conditions: | |
10 // | |
11 // The above copyright notice and this permission notice shall be included in | |
12 // all copies or substantial portions of the Software. | |
13 // | |
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
20 // THE SOFTWARE. | |
21 | |
22 // This file contains a bunch of internal declarations that must appear before async.h can start. | |
23 // We don't define these directly in async.h because it makes the file hard to read. | |
24 | |
25 #pragma once | |
26 | |
27 #include <kj/exception.h> | |
28 #include <kj/tuple.h> | |
29 #include <kj/source-location.h> | |
30 | |
31 // Detect whether or not we should enable kj::Promise<T> coroutine integration. | |
32 // | |
33 // TODO(someday): Support coroutines with -fno-exceptions. | |
34 #if !KJ_NO_EXCEPTIONS | |
35 #ifdef __has_include | |
36 #if (__cpp_impl_coroutine >= 201902L) && __has_include(<coroutine>) | |
37 // C++20 Coroutines detected. | |
38 #include <coroutine> | |
39 #define KJ_HAS_COROUTINE 1 | |
40 #define KJ_COROUTINE_STD_NAMESPACE std | |
41 #elif (__cpp_coroutines >= 201703L) && __has_include(<experimental/coroutine>) | |
42 // Coroutines TS detected. | |
43 #include <experimental/coroutine> | |
44 #define KJ_HAS_COROUTINE 1 | |
45 #define KJ_COROUTINE_STD_NAMESPACE std::experimental | |
46 #endif | |
47 #endif | |
48 #endif | |
49 | |
50 KJ_BEGIN_HEADER | |
51 | |
52 namespace kj { | |
53 | |
54 class EventLoop; | |
55 template <typename T> | |
56 class Promise; | |
57 class WaitScope; | |
58 class TaskSet; | |
59 | |
60 Promise<void> joinPromises(Array<Promise<void>>&& promises, SourceLocation location = {}); | |
61 Promise<void> joinPromisesFailFast(Array<Promise<void>>&& promises, SourceLocation location = {}); | |
62 // Out-of-line <void> specialization of template function defined in async.h. | |
63 | |
64 namespace _ { // private | |
65 | |
66 template <typename T> | |
67 Promise<T> chainPromiseType(T*); | |
68 template <typename T> | |
69 Promise<T> chainPromiseType(Promise<T>*); | |
70 | |
71 template <typename T> | |
72 using ChainPromises = decltype(chainPromiseType((T*)nullptr)); | |
73 // Constructs a promise for T, reducing double-promises. That is, if T is Promise<U>, resolves to | |
74 // Promise<U>, otherwise resolves to Promise<T>. | |
75 | |
76 template <typename T> | |
77 Promise<T> reducePromiseType(T*, ...); | |
78 template <typename T> | |
79 Promise<T> reducePromiseType(Promise<T>*, ...); | |
80 template <typename T, typename Reduced = decltype(T::reducePromise(kj::instance<Promise<T>>()))> | |
81 Reduced reducePromiseType(T*, bool); | |
82 | |
83 template <typename T> | |
84 using ReducePromises = decltype(reducePromiseType((T*)nullptr, false)); | |
85 // Like ChainPromises, but also takes into account whether T has a method `reducePromise` that | |
86 // reduces Promise<T> to something else. In particular this allows Promise<capnp::RemotePromise<U>> | |
87 // to reduce to capnp::RemotePromise<U>. | |
88 | |
89 template <typename T> struct UnwrapPromise_; | |
90 template <typename T> struct UnwrapPromise_<Promise<T>> { typedef T Type; }; | |
91 | |
92 template <typename T> | |
93 using UnwrapPromise = typename UnwrapPromise_<T>::Type; | |
94 | |
95 class PropagateException { | |
96 // A functor which accepts a kj::Exception as a parameter and returns a broken promise of | |
97 // arbitrary type which simply propagates the exception. | |
98 public: | |
99 class Bottom { | |
100 public: | |
101 Bottom(Exception&& exception): exception(kj::mv(exception)) {} | |
102 | |
103 Exception asException() { return kj::mv(exception); } | |
104 | |
105 private: | |
106 Exception exception; | |
107 }; | |
108 | |
109 Bottom operator()(Exception&& e) { | |
110 return Bottom(kj::mv(e)); | |
111 } | |
112 Bottom operator()(const Exception& e) { | |
113 return Bottom(kj::cp(e)); | |
114 } | |
115 }; | |
116 | |
117 template <typename Func, typename T> | |
118 struct ReturnType_ { typedef decltype(instance<Func>()(instance<T>())) Type; }; | |
119 template <typename Func> | |
120 struct ReturnType_<Func, void> { typedef decltype(instance<Func>()()) Type; }; | |
121 | |
122 template <typename Func, typename T> | |
123 using ReturnType = typename ReturnType_<Func, T>::Type; | |
124 // The return type of functor Func given a parameter of type T, with the special exception that if | |
125 // T is void, this is the return type of Func called with no arguments. | |
126 | |
127 template <typename T> struct SplitTuplePromise_ { typedef Promise<T> Type; }; | |
128 template <typename... T> | |
129 struct SplitTuplePromise_<kj::_::Tuple<T...>> { | |
130 typedef kj::Tuple<ReducePromises<T>...> Type; | |
131 }; | |
132 | |
133 template <typename T> | |
134 using SplitTuplePromise = typename SplitTuplePromise_<T>::Type; | |
135 // T -> Promise<T> | |
136 // Tuple<T> -> Tuple<Promise<T>> | |
137 | |
138 struct Void {}; | |
139 // Application code should NOT refer to this! See `kj::READY_NOW` instead. | |
140 | |
141 template <typename T> struct FixVoid_ { typedef T Type; }; | |
142 template <> struct FixVoid_<void> { typedef Void Type; }; | |
143 template <typename T> using FixVoid = typename FixVoid_<T>::Type; | |
144 // FixVoid<T> is just T unless T is void in which case it is _::Void (an empty struct). | |
145 | |
146 template <typename T> struct UnfixVoid_ { typedef T Type; }; | |
147 template <> struct UnfixVoid_<Void> { typedef void Type; }; | |
148 template <typename T> using UnfixVoid = typename UnfixVoid_<T>::Type; | |
149 // UnfixVoid is the opposite of FixVoid. | |
150 | |
151 template <typename In, typename Out> | |
152 struct MaybeVoidCaller { | |
153 // Calls the function converting a Void input to an empty parameter list and a void return | |
154 // value to a Void output. | |
155 | |
156 template <typename Func> | |
157 static inline Out apply(Func& func, In&& in) { | |
158 return func(kj::mv(in)); | |
159 } | |
160 }; | |
161 template <typename In, typename Out> | |
162 struct MaybeVoidCaller<In&, Out> { | |
163 template <typename Func> | |
164 static inline Out apply(Func& func, In& in) { | |
165 return func(in); | |
166 } | |
167 }; | |
168 template <typename Out> | |
169 struct MaybeVoidCaller<Void, Out> { | |
170 template <typename Func> | |
171 static inline Out apply(Func& func, Void&& in) { | |
172 return func(); | |
173 } | |
174 }; | |
175 template <typename In> | |
176 struct MaybeVoidCaller<In, Void> { | |
177 template <typename Func> | |
178 static inline Void apply(Func& func, In&& in) { | |
179 func(kj::mv(in)); | |
180 return Void(); | |
181 } | |
182 }; | |
183 template <typename In> | |
184 struct MaybeVoidCaller<In&, Void> { | |
185 template <typename Func> | |
186 static inline Void apply(Func& func, In& in) { | |
187 func(in); | |
188 return Void(); | |
189 } | |
190 }; | |
191 template <> | |
192 struct MaybeVoidCaller<Void, Void> { | |
193 template <typename Func> | |
194 static inline Void apply(Func& func, Void&& in) { | |
195 func(); | |
196 return Void(); | |
197 } | |
198 }; | |
199 | |
200 template <typename T> | |
201 inline T&& returnMaybeVoid(T&& t) { | |
202 return kj::fwd<T>(t); | |
203 } | |
204 inline void returnMaybeVoid(Void&& v) {} | |
205 | |
206 class ExceptionOrValue; | |
207 class PromiseNode; | |
208 class ChainPromiseNode; | |
209 template <typename T> | |
210 class ForkHub; | |
211 class FiberStack; | |
212 class FiberBase; | |
213 | |
214 class Event; | |
215 class XThreadEvent; | |
216 class XThreadPaf; | |
217 | |
218 class PromiseDisposer; | |
219 using OwnPromiseNode = Own<PromiseNode, PromiseDisposer>; | |
220 // PromiseNode uses a static disposer. | |
221 | |
222 class PromiseBase { | |
223 public: | |
224 kj::String trace(); | |
225 // Dump debug info about this promise. | |
226 | |
227 private: | |
228 OwnPromiseNode node; | |
229 | |
230 PromiseBase() = default; | |
231 PromiseBase(OwnPromiseNode&& node): node(kj::mv(node)) {} | |
232 | |
233 template <typename> | |
234 friend class kj::Promise; | |
235 friend class PromiseNode; | |
236 }; | |
237 | |
238 void detach(kj::Promise<void>&& promise); | |
239 void waitImpl(_::OwnPromiseNode&& node, _::ExceptionOrValue& result, WaitScope& waitScope, | |
240 SourceLocation location); | |
241 bool pollImpl(_::PromiseNode& node, WaitScope& waitScope, SourceLocation location); | |
242 Promise<void> yield(); | |
243 Promise<void> yieldHarder(); | |
244 OwnPromiseNode readyNow(); | |
245 OwnPromiseNode neverDone(); | |
246 | |
247 class ReadyNow { | |
248 public: | |
249 operator Promise<void>() const; | |
250 }; | |
251 | |
252 class NeverDone { | |
253 public: | |
254 template <typename T> | |
255 operator Promise<T>() const; | |
256 | |
257 KJ_NORETURN(void wait(WaitScope& waitScope, SourceLocation location = {}) const); | |
258 }; | |
259 | |
260 } // namespace _ (private) | |
261 } // namespace kj | |
262 | |
263 KJ_END_HEADER |