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