annotate osx/include/kj/async.h @ 140:59a8758c56b1

Add source for PortAudio stable v190600_20161030
author Chris Cannam <cannam@all-day-breakfast.com>
date Tue, 03 Jan 2017 13:44:07 +0000
parents 41e769c91eca
children 0994c39f1e94
rev   line source
cannam@134 1 // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
cannam@134 2 // Licensed under the MIT License:
cannam@134 3 //
cannam@134 4 // Permission is hereby granted, free of charge, to any person obtaining a copy
cannam@134 5 // of this software and associated documentation files (the "Software"), to deal
cannam@134 6 // in the Software without restriction, including without limitation the rights
cannam@134 7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
cannam@134 8 // copies of the Software, and to permit persons to whom the Software is
cannam@134 9 // furnished to do so, subject to the following conditions:
cannam@134 10 //
cannam@134 11 // The above copyright notice and this permission notice shall be included in
cannam@134 12 // all copies or substantial portions of the Software.
cannam@134 13 //
cannam@134 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
cannam@134 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
cannam@134 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
cannam@134 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
cannam@134 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
cannam@134 19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
cannam@134 20 // THE SOFTWARE.
cannam@134 21
cannam@134 22 #ifndef KJ_ASYNC_H_
cannam@134 23 #define KJ_ASYNC_H_
cannam@134 24
cannam@134 25 #if defined(__GNUC__) && !KJ_HEADER_WARNINGS
cannam@134 26 #pragma GCC system_header
cannam@134 27 #endif
cannam@134 28
cannam@134 29 #include "async-prelude.h"
cannam@134 30 #include "exception.h"
cannam@134 31 #include "refcount.h"
cannam@134 32
cannam@134 33 namespace kj {
cannam@134 34
cannam@134 35 class EventLoop;
cannam@134 36 class WaitScope;
cannam@134 37
cannam@134 38 template <typename T>
cannam@134 39 class Promise;
cannam@134 40 template <typename T>
cannam@134 41 class ForkedPromise;
cannam@134 42 template <typename T>
cannam@134 43 class PromiseFulfiller;
cannam@134 44 template <typename T>
cannam@134 45 struct PromiseFulfillerPair;
cannam@134 46
cannam@134 47 template <typename Func, typename T>
cannam@134 48 using PromiseForResult = Promise<_::JoinPromises<_::ReturnType<Func, T>>>;
cannam@134 49 // Evaluates to the type of Promise for the result of calling functor type Func with parameter type
cannam@134 50 // T. If T is void, then the promise is for the result of calling Func with no arguments. If
cannam@134 51 // Func itself returns a promise, the promises are joined, so you never get Promise<Promise<T>>.
cannam@134 52
cannam@134 53 // =======================================================================================
cannam@134 54 // Promises
cannam@134 55
cannam@134 56 template <typename T>
cannam@134 57 class Promise: protected _::PromiseBase {
cannam@134 58 // The basic primitive of asynchronous computation in KJ. Similar to "futures", but designed
cannam@134 59 // specifically for event loop concurrency. Similar to E promises and JavaScript Promises/A.
cannam@134 60 //
cannam@134 61 // A Promise represents a promise to produce a value of type T some time in the future. Once
cannam@134 62 // that value has been produced, the promise is "fulfilled". Alternatively, a promise can be
cannam@134 63 // "broken", with an Exception describing what went wrong. You may implicitly convert a value of
cannam@134 64 // type T to an already-fulfilled Promise<T>. You may implicitly convert the constant
cannam@134 65 // `kj::READY_NOW` to an already-fulfilled Promise<void>. You may also implicitly convert a
cannam@134 66 // `kj::Exception` to an already-broken promise of any type.
cannam@134 67 //
cannam@134 68 // Promises are linear types -- they are moveable but not copyable. If a Promise is destroyed
cannam@134 69 // or goes out of scope (without being moved elsewhere), any ongoing asynchronous operations
cannam@134 70 // meant to fulfill the promise will be canceled if possible. All methods of `Promise` (unless
cannam@134 71 // otherwise noted) actually consume the promise in the sense of move semantics. (Arguably they
cannam@134 72 // should be rvalue-qualified, but at the time this interface was created compilers didn't widely
cannam@134 73 // support that yet and anyway it would be pretty ugly typing kj::mv(promise).whatever().) If
cannam@134 74 // you want to use one Promise in two different places, you must fork it with `fork()`.
cannam@134 75 //
cannam@134 76 // To use the result of a Promise, you must call `then()` and supply a callback function to
cannam@134 77 // call with the result. `then()` returns another promise, for the result of the callback.
cannam@134 78 // Any time that this would result in Promise<Promise<T>>, the promises are collapsed into a
cannam@134 79 // simple Promise<T> that first waits for the outer promise, then the inner. Example:
cannam@134 80 //
cannam@134 81 // // Open a remote file, read the content, and then count the
cannam@134 82 // // number of lines of text.
cannam@134 83 // // Note that none of the calls here block. `file`, `content`
cannam@134 84 // // and `lineCount` are all initialized immediately before any
cannam@134 85 // // asynchronous operations occur. The lambda callbacks are
cannam@134 86 // // called later.
cannam@134 87 // Promise<Own<File>> file = openFtp("ftp://host/foo/bar");
cannam@134 88 // Promise<String> content = file.then(
cannam@134 89 // [](Own<File> file) -> Promise<String> {
cannam@134 90 // return file.readAll();
cannam@134 91 // });
cannam@134 92 // Promise<int> lineCount = content.then(
cannam@134 93 // [](String text) -> int {
cannam@134 94 // uint count = 0;
cannam@134 95 // for (char c: text) count += (c == '\n');
cannam@134 96 // return count;
cannam@134 97 // });
cannam@134 98 //
cannam@134 99 // For `then()` to work, the current thread must have an active `EventLoop`. Each callback
cannam@134 100 // is scheduled to execute in that loop. Since `then()` schedules callbacks only on the current
cannam@134 101 // thread's event loop, you do not need to worry about two callbacks running at the same time.
cannam@134 102 // You will need to set up at least one `EventLoop` at the top level of your program before you
cannam@134 103 // can use promises.
cannam@134 104 //
cannam@134 105 // To adapt a non-Promise-based asynchronous API to promises, use `newAdaptedPromise()`.
cannam@134 106 //
cannam@134 107 // Systems using promises should consider supporting the concept of "pipelining". Pipelining
cannam@134 108 // means allowing a caller to start issuing method calls against a promised object before the
cannam@134 109 // promise has actually been fulfilled. This is particularly useful if the promise is for a
cannam@134 110 // remote object living across a network, as this can avoid round trips when chaining a series
cannam@134 111 // of calls. It is suggested that any class T which supports pipelining implement a subclass of
cannam@134 112 // Promise<T> which adds "eventual send" methods -- methods which, when called, say "please
cannam@134 113 // invoke the corresponding method on the promised value once it is available". These methods
cannam@134 114 // should in turn return promises for the eventual results of said invocations. Cap'n Proto,
cannam@134 115 // for example, implements the type `RemotePromise` which supports pipelining RPC requests -- see
cannam@134 116 // `capnp/capability.h`.
cannam@134 117 //
cannam@134 118 // KJ Promises are based on E promises:
cannam@134 119 // http://wiki.erights.org/wiki/Walnut/Distributed_Computing#Promises
cannam@134 120 //
cannam@134 121 // KJ Promises are also inspired in part by the evolving standards for JavaScript/ECMAScript
cannam@134 122 // promises, which are themselves influenced by E promises:
cannam@134 123 // http://promisesaplus.com/
cannam@134 124 // https://github.com/domenic/promises-unwrapping
cannam@134 125
cannam@134 126 public:
cannam@134 127 Promise(_::FixVoid<T> value);
cannam@134 128 // Construct an already-fulfilled Promise from a value of type T. For non-void promises, the
cannam@134 129 // parameter type is simply T. So, e.g., in a function that returns `Promise<int>`, you can
cannam@134 130 // say `return 123;` to return a promise that is already fulfilled to 123.
cannam@134 131 //
cannam@134 132 // For void promises, use `kj::READY_NOW` as the value, e.g. `return kj::READY_NOW`.
cannam@134 133
cannam@134 134 Promise(kj::Exception&& e);
cannam@134 135 // Construct an already-broken Promise.
cannam@134 136
cannam@134 137 inline Promise(decltype(nullptr)) {}
cannam@134 138
cannam@134 139 template <typename Func, typename ErrorFunc = _::PropagateException>
cannam@134 140 PromiseForResult<Func, T> then(Func&& func, ErrorFunc&& errorHandler = _::PropagateException())
cannam@134 141 KJ_WARN_UNUSED_RESULT;
cannam@134 142 // Register a continuation function to be executed when the promise completes. The continuation
cannam@134 143 // (`func`) takes the promised value (an rvalue of type `T`) as its parameter. The continuation
cannam@134 144 // may return a new value; `then()` itself returns a promise for the continuation's eventual
cannam@134 145 // result. If the continuation itself returns a `Promise<U>`, then `then()` shall also return
cannam@134 146 // a `Promise<U>` which first waits for the original promise, then executes the continuation,
cannam@134 147 // then waits for the inner promise (i.e. it automatically "unwraps" the promise).
cannam@134 148 //
cannam@134 149 // In all cases, `then()` returns immediately. The continuation is executed later. The
cannam@134 150 // continuation is always executed on the same EventLoop (and, therefore, the same thread) which
cannam@134 151 // called `then()`, therefore no synchronization is necessary on state shared by the continuation
cannam@134 152 // and the surrounding scope. If no EventLoop is running on the current thread, `then()` throws
cannam@134 153 // an exception.
cannam@134 154 //
cannam@134 155 // You may also specify an error handler continuation as the second parameter. `errorHandler`
cannam@134 156 // must be a functor taking a parameter of type `kj::Exception&&`. It must return the same
cannam@134 157 // type as `func` returns (except when `func` returns `Promise<U>`, in which case `errorHandler`
cannam@134 158 // may return either `Promise<U>` or just `U`). The default error handler simply propagates the
cannam@134 159 // exception to the returned promise.
cannam@134 160 //
cannam@134 161 // Either `func` or `errorHandler` may, of course, throw an exception, in which case the promise
cannam@134 162 // is broken. When compiled with -fno-exceptions, the framework will still detect when a
cannam@134 163 // recoverable exception was thrown inside of a continuation and will consider the promise
cannam@134 164 // broken even though a (presumably garbage) result was returned.
cannam@134 165 //
cannam@134 166 // If the returned promise is destroyed before the callback runs, the callback will be canceled
cannam@134 167 // (it will never run).
cannam@134 168 //
cannam@134 169 // Note that `then()` -- like all other Promise methods -- consumes the promise on which it is
cannam@134 170 // called, in the sense of move semantics. After returning, the original promise is no longer
cannam@134 171 // valid, but `then()` returns a new promise.
cannam@134 172 //
cannam@134 173 // *Advanced implementation tips:* Most users will never need to worry about the below, but
cannam@134 174 // it is good to be aware of.
cannam@134 175 //
cannam@134 176 // As an optimization, if the callback function `func` does _not_ return another promise, then
cannam@134 177 // execution of `func` itself may be delayed until its result is known to be needed. The
cannam@134 178 // expectation here is that `func` is just doing some transformation on the results, not
cannam@134 179 // scheduling any other actions, therefore the system doesn't need to be proactive about
cannam@134 180 // evaluating it. This way, a chain of trivial then() transformations can be executed all at
cannam@134 181 // once without repeatedly re-scheduling through the event loop. Use the `eagerlyEvaluate()`
cannam@134 182 // method to suppress this behavior.
cannam@134 183 //
cannam@134 184 // On the other hand, if `func` _does_ return another promise, then the system evaluates `func`
cannam@134 185 // as soon as possible, because the promise it returns might be for a newly-scheduled
cannam@134 186 // long-running asynchronous task.
cannam@134 187 //
cannam@134 188 // As another optimization, when a callback function registered with `then()` is actually
cannam@134 189 // scheduled, it is scheduled to occur immediately, preempting other work in the event queue.
cannam@134 190 // This allows a long chain of `then`s to execute all at once, improving cache locality by
cannam@134 191 // clustering operations on the same data. However, this implies that starvation can occur
cannam@134 192 // if a chain of `then()`s takes a very long time to execute without ever stopping to wait for
cannam@134 193 // actual I/O. To solve this, use `kj::evalLater()` to yield control; this way, all other events
cannam@134 194 // in the queue will get a chance to run before your callback is executed.
cannam@134 195
cannam@134 196 Promise<void> ignoreResult() KJ_WARN_UNUSED_RESULT { return then([](T&&) {}); }
cannam@134 197 // Convenience method to convert the promise to a void promise by ignoring the return value.
cannam@134 198 //
cannam@134 199 // You must still wait on the returned promise if you want the task to execute.
cannam@134 200
cannam@134 201 template <typename ErrorFunc>
cannam@134 202 Promise<T> catch_(ErrorFunc&& errorHandler) KJ_WARN_UNUSED_RESULT;
cannam@134 203 // Equivalent to `.then(identityFunc, errorHandler)`, where `identifyFunc` is a function that
cannam@134 204 // just returns its input.
cannam@134 205
cannam@134 206 T wait(WaitScope& waitScope);
cannam@134 207 // Run the event loop until the promise is fulfilled, then return its result. If the promise
cannam@134 208 // is rejected, throw an exception.
cannam@134 209 //
cannam@134 210 // wait() is primarily useful at the top level of a program -- typically, within the function
cannam@134 211 // that allocated the EventLoop. For example, a program that performs one or two RPCs and then
cannam@134 212 // exits would likely use wait() in its main() function to wait on each RPC. On the other hand,
cannam@134 213 // server-side code generally cannot use wait(), because it has to be able to accept multiple
cannam@134 214 // requests at once.
cannam@134 215 //
cannam@134 216 // If the promise is rejected, `wait()` throws an exception. If the program was compiled without
cannam@134 217 // exceptions (-fno-exceptions), this will usually abort. In this case you really should first
cannam@134 218 // use `then()` to set an appropriate handler for the exception case, so that the promise you
cannam@134 219 // actually wait on never throws.
cannam@134 220 //
cannam@134 221 // `waitScope` is an object proving that the caller is in a scope where wait() is allowed. By
cannam@134 222 // convention, any function which might call wait(), or which might call another function which
cannam@134 223 // might call wait(), must take `WaitScope&` as one of its parameters. This is needed for two
cannam@134 224 // reasons:
cannam@134 225 // * `wait()` is not allowed during an event callback, because event callbacks are themselves
cannam@134 226 // called during some other `wait()`, and such recursive `wait()`s would only be able to
cannam@134 227 // complete in LIFO order, which might mean that the outer `wait()` ends up waiting longer
cannam@134 228 // than it is supposed to. To prevent this, a `WaitScope` cannot be constructed or used during
cannam@134 229 // an event callback.
cannam@134 230 // * Since `wait()` runs the event loop, unrelated event callbacks may execute before `wait()`
cannam@134 231 // returns. This means that anyone calling `wait()` must be reentrant -- state may change
cannam@134 232 // around them in arbitrary ways. Therefore, callers really need to know if a function they
cannam@134 233 // are calling might wait(), and the `WaitScope&` parameter makes this clear.
cannam@134 234 //
cannam@134 235 // TODO(someday): Implement fibers, and let them call wait() even when they are handling an
cannam@134 236 // event.
cannam@134 237
cannam@134 238 ForkedPromise<T> fork() KJ_WARN_UNUSED_RESULT;
cannam@134 239 // Forks the promise, so that multiple different clients can independently wait on the result.
cannam@134 240 // `T` must be copy-constructable for this to work. Or, in the special case where `T` is
cannam@134 241 // `Own<U>`, `U` must have a method `Own<U> addRef()` which returns a new reference to the same
cannam@134 242 // (or an equivalent) object (probably implemented via reference counting).
cannam@134 243
cannam@134 244 _::SplitTuplePromise<T> split();
cannam@134 245 // Split a promise for a tuple into a tuple of promises.
cannam@134 246 //
cannam@134 247 // E.g. if you have `Promise<kj::Tuple<T, U>>`, `split()` returns
cannam@134 248 // `kj::Tuple<Promise<T>, Promise<U>>`.
cannam@134 249
cannam@134 250 Promise<T> exclusiveJoin(Promise<T>&& other) KJ_WARN_UNUSED_RESULT;
cannam@134 251 // Return a new promise that resolves when either the original promise resolves or `other`
cannam@134 252 // resolves (whichever comes first). The promise that didn't resolve first is canceled.
cannam@134 253
cannam@134 254 // TODO(someday): inclusiveJoin(), or perhaps just join(), which waits for both completions
cannam@134 255 // and produces a tuple?
cannam@134 256
cannam@134 257 template <typename... Attachments>
cannam@134 258 Promise<T> attach(Attachments&&... attachments) KJ_WARN_UNUSED_RESULT;
cannam@134 259 // "Attaches" one or more movable objects (often, Own<T>s) to the promise, such that they will
cannam@134 260 // be destroyed when the promise resolves. This is useful when a promise's callback contains
cannam@134 261 // pointers into some object and you want to make sure the object still exists when the callback
cannam@134 262 // runs -- after calling then(), use attach() to add necessary objects to the result.
cannam@134 263
cannam@134 264 template <typename ErrorFunc>
cannam@134 265 Promise<T> eagerlyEvaluate(ErrorFunc&& errorHandler) KJ_WARN_UNUSED_RESULT;
cannam@134 266 Promise<T> eagerlyEvaluate(decltype(nullptr)) KJ_WARN_UNUSED_RESULT;
cannam@134 267 // Force eager evaluation of this promise. Use this if you are going to hold on to the promise
cannam@134 268 // for awhile without consuming the result, but you want to make sure that the system actually
cannam@134 269 // processes it.
cannam@134 270 //
cannam@134 271 // `errorHandler` is a function that takes `kj::Exception&&`, like the second parameter to
cannam@134 272 // `then()`, except that it must return void. We make you specify this because otherwise it's
cannam@134 273 // easy to forget to handle errors in a promise that you never use. You may specify nullptr for
cannam@134 274 // the error handler if you are sure that ignoring errors is fine, or if you know that you'll
cannam@134 275 // eventually wait on the promise somewhere.
cannam@134 276
cannam@134 277 template <typename ErrorFunc>
cannam@134 278 void detach(ErrorFunc&& errorHandler);
cannam@134 279 // Allows the promise to continue running in the background until it completes or the
cannam@134 280 // `EventLoop` is destroyed. Be careful when using this: since you can no longer cancel this
cannam@134 281 // promise, you need to make sure that the promise owns all the objects it touches or make sure
cannam@134 282 // those objects outlive the EventLoop.
cannam@134 283 //
cannam@134 284 // `errorHandler` is a function that takes `kj::Exception&&`, like the second parameter to
cannam@134 285 // `then()`, except that it must return void.
cannam@134 286 //
cannam@134 287 // This function exists mainly to implement the Cap'n Proto requirement that RPC calls cannot be
cannam@134 288 // canceled unless the callee explicitly permits it.
cannam@134 289
cannam@134 290 kj::String trace();
cannam@134 291 // Returns a dump of debug info about this promise. Not for production use. Requires RTTI.
cannam@134 292 // This method does NOT consume the promise as other methods do.
cannam@134 293
cannam@134 294 private:
cannam@134 295 Promise(bool, Own<_::PromiseNode>&& node): PromiseBase(kj::mv(node)) {}
cannam@134 296 // Second parameter prevent ambiguity with immediate-value constructor.
cannam@134 297
cannam@134 298 template <typename>
cannam@134 299 friend class Promise;
cannam@134 300 friend class EventLoop;
cannam@134 301 template <typename U, typename Adapter, typename... Params>
cannam@134 302 friend Promise<U> newAdaptedPromise(Params&&... adapterConstructorParams);
cannam@134 303 template <typename U>
cannam@134 304 friend PromiseFulfillerPair<U> newPromiseAndFulfiller();
cannam@134 305 template <typename>
cannam@134 306 friend class _::ForkHub;
cannam@134 307 friend class _::TaskSetImpl;
cannam@134 308 friend Promise<void> _::yield();
cannam@134 309 friend class _::NeverDone;
cannam@134 310 template <typename U>
cannam@134 311 friend Promise<Array<U>> joinPromises(Array<Promise<U>>&& promises);
cannam@134 312 friend Promise<void> joinPromises(Array<Promise<void>>&& promises);
cannam@134 313 };
cannam@134 314
cannam@134 315 template <typename T>
cannam@134 316 class ForkedPromise {
cannam@134 317 // The result of `Promise::fork()` and `EventLoop::fork()`. Allows branches to be created.
cannam@134 318 // Like `Promise<T>`, this is a pass-by-move type.
cannam@134 319
cannam@134 320 public:
cannam@134 321 inline ForkedPromise(decltype(nullptr)) {}
cannam@134 322
cannam@134 323 Promise<T> addBranch();
cannam@134 324 // Add a new branch to the fork. The branch is equivalent to the original promise.
cannam@134 325
cannam@134 326 private:
cannam@134 327 Own<_::ForkHub<_::FixVoid<T>>> hub;
cannam@134 328
cannam@134 329 inline ForkedPromise(bool, Own<_::ForkHub<_::FixVoid<T>>>&& hub): hub(kj::mv(hub)) {}
cannam@134 330
cannam@134 331 friend class Promise<T>;
cannam@134 332 friend class EventLoop;
cannam@134 333 };
cannam@134 334
cannam@134 335 constexpr _::Void READY_NOW = _::Void();
cannam@134 336 // Use this when you need a Promise<void> that is already fulfilled -- this value can be implicitly
cannam@134 337 // cast to `Promise<void>`.
cannam@134 338
cannam@134 339 constexpr _::NeverDone NEVER_DONE = _::NeverDone();
cannam@134 340 // The opposite of `READY_NOW`, return this when the promise should never resolve. This can be
cannam@134 341 // implicitly converted to any promise type. You may also call `NEVER_DONE.wait()` to wait
cannam@134 342 // forever (useful for servers).
cannam@134 343
cannam@134 344 template <typename Func>
cannam@134 345 PromiseForResult<Func, void> evalLater(Func&& func) KJ_WARN_UNUSED_RESULT;
cannam@134 346 // Schedule for the given zero-parameter function to be executed in the event loop at some
cannam@134 347 // point in the near future. Returns a Promise for its result -- or, if `func()` itself returns
cannam@134 348 // a promise, `evalLater()` returns a Promise for the result of resolving that promise.
cannam@134 349 //
cannam@134 350 // Example usage:
cannam@134 351 // Promise<int> x = evalLater([]() { return 123; });
cannam@134 352 //
cannam@134 353 // The above is exactly equivalent to:
cannam@134 354 // Promise<int> x = Promise<void>(READY_NOW).then([]() { return 123; });
cannam@134 355 //
cannam@134 356 // If the returned promise is destroyed before the callback runs, the callback will be canceled
cannam@134 357 // (never called).
cannam@134 358 //
cannam@134 359 // If you schedule several evaluations with `evalLater` during the same callback, they are
cannam@134 360 // guaranteed to be executed in order.
cannam@134 361
cannam@134 362 template <typename Func>
cannam@134 363 PromiseForResult<Func, void> evalNow(Func&& func) KJ_WARN_UNUSED_RESULT;
cannam@134 364 // Run `func()` and return a promise for its result. `func()` executes before `evalNow()` returns.
cannam@134 365 // If `func()` throws an exception, the exception is caught and wrapped in a promise -- this is the
cannam@134 366 // main reason why `evalNow()` is useful.
cannam@134 367
cannam@134 368 template <typename T>
cannam@134 369 Promise<Array<T>> joinPromises(Array<Promise<T>>&& promises);
cannam@134 370 // Join an array of promises into a promise for an array.
cannam@134 371
cannam@134 372 // =======================================================================================
cannam@134 373 // Hack for creating a lambda that holds an owned pointer.
cannam@134 374
cannam@134 375 template <typename Func, typename MovedParam>
cannam@134 376 class CaptureByMove {
cannam@134 377 public:
cannam@134 378 inline CaptureByMove(Func&& func, MovedParam&& param)
cannam@134 379 : func(kj::mv(func)), param(kj::mv(param)) {}
cannam@134 380
cannam@134 381 template <typename... Params>
cannam@134 382 inline auto operator()(Params&&... params)
cannam@134 383 -> decltype(kj::instance<Func>()(kj::instance<MovedParam&&>(), kj::fwd<Params>(params)...)) {
cannam@134 384 return func(kj::mv(param), kj::fwd<Params>(params)...);
cannam@134 385 }
cannam@134 386
cannam@134 387 private:
cannam@134 388 Func func;
cannam@134 389 MovedParam param;
cannam@134 390 };
cannam@134 391
cannam@134 392 template <typename Func, typename MovedParam>
cannam@134 393 inline CaptureByMove<Func, Decay<MovedParam>> mvCapture(MovedParam&& param, Func&& func) {
cannam@134 394 // Hack to create a "lambda" which captures a variable by moving it rather than copying or
cannam@134 395 // referencing. C++14 generalized captures should make this obsolete, but for now in C++11 this
cannam@134 396 // is commonly needed for Promise continuations that own their state. Example usage:
cannam@134 397 //
cannam@134 398 // Own<Foo> ptr = makeFoo();
cannam@134 399 // Promise<int> promise = callRpc();
cannam@134 400 // promise.then(mvCapture(ptr, [](Own<Foo>&& ptr, int result) {
cannam@134 401 // return ptr->finish(result);
cannam@134 402 // }));
cannam@134 403
cannam@134 404 return CaptureByMove<Func, Decay<MovedParam>>(kj::fwd<Func>(func), kj::mv(param));
cannam@134 405 }
cannam@134 406
cannam@134 407 // =======================================================================================
cannam@134 408 // Advanced promise construction
cannam@134 409
cannam@134 410 template <typename T>
cannam@134 411 class PromiseFulfiller {
cannam@134 412 // A callback which can be used to fulfill a promise. Only the first call to fulfill() or
cannam@134 413 // reject() matters; subsequent calls are ignored.
cannam@134 414
cannam@134 415 public:
cannam@134 416 virtual void fulfill(T&& value) = 0;
cannam@134 417 // Fulfill the promise with the given value.
cannam@134 418
cannam@134 419 virtual void reject(Exception&& exception) = 0;
cannam@134 420 // Reject the promise with an error.
cannam@134 421
cannam@134 422 virtual bool isWaiting() = 0;
cannam@134 423 // Returns true if the promise is still unfulfilled and someone is potentially waiting for it.
cannam@134 424 // Returns false if fulfill()/reject() has already been called *or* if the promise to be
cannam@134 425 // fulfilled has been discarded and therefore the result will never be used anyway.
cannam@134 426
cannam@134 427 template <typename Func>
cannam@134 428 bool rejectIfThrows(Func&& func);
cannam@134 429 // Call the function (with no arguments) and return true. If an exception is thrown, call
cannam@134 430 // `fulfiller.reject()` and then return false. When compiled with exceptions disabled,
cannam@134 431 // non-fatal exceptions are still detected and handled correctly.
cannam@134 432 };
cannam@134 433
cannam@134 434 template <>
cannam@134 435 class PromiseFulfiller<void> {
cannam@134 436 // Specialization of PromiseFulfiller for void promises. See PromiseFulfiller<T>.
cannam@134 437
cannam@134 438 public:
cannam@134 439 virtual void fulfill(_::Void&& value = _::Void()) = 0;
cannam@134 440 // Call with zero parameters. The parameter is a dummy that only exists so that subclasses don't
cannam@134 441 // have to specialize for <void>.
cannam@134 442
cannam@134 443 virtual void reject(Exception&& exception) = 0;
cannam@134 444 virtual bool isWaiting() = 0;
cannam@134 445
cannam@134 446 template <typename Func>
cannam@134 447 bool rejectIfThrows(Func&& func);
cannam@134 448 };
cannam@134 449
cannam@134 450 template <typename T, typename Adapter, typename... Params>
cannam@134 451 Promise<T> newAdaptedPromise(Params&&... adapterConstructorParams);
cannam@134 452 // Creates a new promise which owns an instance of `Adapter` which encapsulates the operation
cannam@134 453 // that will eventually fulfill the promise. This is primarily useful for adapting non-KJ
cannam@134 454 // asynchronous APIs to use promises.
cannam@134 455 //
cannam@134 456 // An instance of `Adapter` will be allocated and owned by the returned `Promise`. A
cannam@134 457 // `PromiseFulfiller<T>&` will be passed as the first parameter to the adapter's constructor,
cannam@134 458 // and `adapterConstructorParams` will be forwarded as the subsequent parameters. The adapter
cannam@134 459 // is expected to perform some asynchronous operation and call the `PromiseFulfiller<T>` once
cannam@134 460 // it is finished.
cannam@134 461 //
cannam@134 462 // The adapter is destroyed when its owning Promise is destroyed. This may occur before the
cannam@134 463 // Promise has been fulfilled. In this case, the adapter's destructor should cancel the
cannam@134 464 // asynchronous operation. Once the adapter is destroyed, the fulfillment callback cannot be
cannam@134 465 // called.
cannam@134 466 //
cannam@134 467 // An adapter implementation should be carefully written to ensure that it cannot accidentally
cannam@134 468 // be left unfulfilled permanently because of an exception. Consider making liberal use of
cannam@134 469 // `PromiseFulfiller<T>::rejectIfThrows()`.
cannam@134 470
cannam@134 471 template <typename T>
cannam@134 472 struct PromiseFulfillerPair {
cannam@134 473 Promise<_::JoinPromises<T>> promise;
cannam@134 474 Own<PromiseFulfiller<T>> fulfiller;
cannam@134 475 };
cannam@134 476
cannam@134 477 template <typename T>
cannam@134 478 PromiseFulfillerPair<T> newPromiseAndFulfiller();
cannam@134 479 // Construct a Promise and a separate PromiseFulfiller which can be used to fulfill the promise.
cannam@134 480 // If the PromiseFulfiller is destroyed before either of its methods are called, the Promise is
cannam@134 481 // implicitly rejected.
cannam@134 482 //
cannam@134 483 // Although this function is easier to use than `newAdaptedPromise()`, it has the serious drawback
cannam@134 484 // that there is no way to handle cancellation (i.e. detect when the Promise is discarded).
cannam@134 485 //
cannam@134 486 // You can arrange to fulfill a promise with another promise by using a promise type for T. E.g.
cannam@134 487 // `newPromiseAndFulfiller<Promise<U>>()` will produce a promise of type `Promise<U>` but the
cannam@134 488 // fulfiller will be of type `PromiseFulfiller<Promise<U>>`. Thus you pass a `Promise<U>` to the
cannam@134 489 // `fulfill()` callback, and the promises are chained.
cannam@134 490
cannam@134 491 // =======================================================================================
cannam@134 492 // TaskSet
cannam@134 493
cannam@134 494 class TaskSet {
cannam@134 495 // Holds a collection of Promise<void>s and ensures that each executes to completion. Memory
cannam@134 496 // associated with each promise is automatically freed when the promise completes. Destroying
cannam@134 497 // the TaskSet itself automatically cancels all unfinished promises.
cannam@134 498 //
cannam@134 499 // This is useful for "daemon" objects that perform background tasks which aren't intended to
cannam@134 500 // fulfill any particular external promise, but which may need to be canceled (and thus can't
cannam@134 501 // use `Promise::detach()`). The daemon object holds a TaskSet to collect these tasks it is
cannam@134 502 // working on. This way, if the daemon itself is destroyed, the TaskSet is detroyed as well,
cannam@134 503 // and everything the daemon is doing is canceled.
cannam@134 504
cannam@134 505 public:
cannam@134 506 class ErrorHandler {
cannam@134 507 public:
cannam@134 508 virtual void taskFailed(kj::Exception&& exception) = 0;
cannam@134 509 };
cannam@134 510
cannam@134 511 TaskSet(ErrorHandler& errorHandler);
cannam@134 512 // `loop` will be used to wait on promises. `errorHandler` will be executed any time a task
cannam@134 513 // throws an exception, and will execute within the given EventLoop.
cannam@134 514
cannam@134 515 ~TaskSet() noexcept(false);
cannam@134 516
cannam@134 517 void add(Promise<void>&& promise);
cannam@134 518
cannam@134 519 kj::String trace();
cannam@134 520 // Return debug info about all promises currently in the TaskSet.
cannam@134 521
cannam@134 522 private:
cannam@134 523 Own<_::TaskSetImpl> impl;
cannam@134 524 };
cannam@134 525
cannam@134 526 // =======================================================================================
cannam@134 527 // The EventLoop class
cannam@134 528
cannam@134 529 class EventPort {
cannam@134 530 // Interfaces between an `EventLoop` and events originating from outside of the loop's thread.
cannam@134 531 // All such events come in through the `EventPort` implementation.
cannam@134 532 //
cannam@134 533 // An `EventPort` implementation may interface with low-level operating system APIs and/or other
cannam@134 534 // threads. You can also write an `EventPort` which wraps some other (non-KJ) event loop
cannam@134 535 // framework, allowing the two to coexist in a single thread.
cannam@134 536
cannam@134 537 public:
cannam@134 538 virtual bool wait() = 0;
cannam@134 539 // Wait for an external event to arrive, sleeping if necessary. Once at least one event has
cannam@134 540 // arrived, queue it to the event loop (e.g. by fulfilling a promise) and return.
cannam@134 541 //
cannam@134 542 // This is called during `Promise::wait()` whenever the event queue becomes empty, in order to
cannam@134 543 // wait for new events to populate the queue.
cannam@134 544 //
cannam@134 545 // It is safe to return even if nothing has actually been queued, so long as calling `wait()` in
cannam@134 546 // a loop will eventually sleep. (That is to say, false positives are fine.)
cannam@134 547 //
cannam@134 548 // Returns true if wake() has been called from another thread. (Precisely, returns true if
cannam@134 549 // no previous call to wait `wait()` nor `poll()` has returned true since `wake()` was last
cannam@134 550 // called.)
cannam@134 551
cannam@134 552 virtual bool poll() = 0;
cannam@134 553 // Check if any external events have arrived, but do not sleep. If any events have arrived,
cannam@134 554 // add them to the event queue (e.g. by fulfilling promises) before returning.
cannam@134 555 //
cannam@134 556 // This may be called during `Promise::wait()` when the EventLoop has been executing for a while
cannam@134 557 // without a break but is still non-empty.
cannam@134 558 //
cannam@134 559 // Returns true if wake() has been called from another thread. (Precisely, returns true if
cannam@134 560 // no previous call to wait `wait()` nor `poll()` has returned true since `wake()` was last
cannam@134 561 // called.)
cannam@134 562
cannam@134 563 virtual void setRunnable(bool runnable);
cannam@134 564 // Called to notify the `EventPort` when the `EventLoop` has work to do; specifically when it
cannam@134 565 // transitions from empty -> runnable or runnable -> empty. This is typically useful when
cannam@134 566 // integrating with an external event loop; if the loop is currently runnable then you should
cannam@134 567 // arrange to call run() on it soon. The default implementation does nothing.
cannam@134 568
cannam@134 569 virtual void wake() const;
cannam@134 570 // Wake up the EventPort's thread from another thread.
cannam@134 571 //
cannam@134 572 // Unlike all other methods on this interface, `wake()` may be called from another thread, hence
cannam@134 573 // it is `const`.
cannam@134 574 //
cannam@134 575 // Technically speaking, `wake()` causes the target thread to cease sleeping and not to sleep
cannam@134 576 // again until `wait()` or `poll()` has returned true at least once.
cannam@134 577 //
cannam@134 578 // The default implementation throws an UNIMPLEMENTED exception.
cannam@134 579 };
cannam@134 580
cannam@134 581 class EventLoop {
cannam@134 582 // Represents a queue of events being executed in a loop. Most code won't interact with
cannam@134 583 // EventLoop directly, but instead use `Promise`s to interact with it indirectly. See the
cannam@134 584 // documentation for `Promise`.
cannam@134 585 //
cannam@134 586 // Each thread can have at most one current EventLoop. To make an `EventLoop` current for
cannam@134 587 // the thread, create a `WaitScope`. Async APIs require that the thread has a current EventLoop,
cannam@134 588 // or they will throw exceptions. APIs that use `Promise::wait()` additionally must explicitly
cannam@134 589 // be passed a reference to the `WaitScope` to make the caller aware that they might block.
cannam@134 590 //
cannam@134 591 // Generally, you will want to construct an `EventLoop` at the top level of your program, e.g.
cannam@134 592 // in the main() function, or in the start function of a thread. You can then use it to
cannam@134 593 // construct some promises and wait on the result. Example:
cannam@134 594 //
cannam@134 595 // int main() {
cannam@134 596 // // `loop` becomes the official EventLoop for the thread.
cannam@134 597 // MyEventPort eventPort;
cannam@134 598 // EventLoop loop(eventPort);
cannam@134 599 //
cannam@134 600 // // Now we can call an async function.
cannam@134 601 // Promise<String> textPromise = getHttp("http://example.com");
cannam@134 602 //
cannam@134 603 // // And we can wait for the promise to complete. Note that you can only use `wait()`
cannam@134 604 // // from the top level, not from inside a promise callback.
cannam@134 605 // String text = textPromise.wait();
cannam@134 606 // print(text);
cannam@134 607 // return 0;
cannam@134 608 // }
cannam@134 609 //
cannam@134 610 // Most applications that do I/O will prefer to use `setupAsyncIo()` from `async-io.h` rather
cannam@134 611 // than allocate an `EventLoop` directly.
cannam@134 612
cannam@134 613 public:
cannam@134 614 EventLoop();
cannam@134 615 // Construct an `EventLoop` which does not receive external events at all.
cannam@134 616
cannam@134 617 explicit EventLoop(EventPort& port);
cannam@134 618 // Construct an `EventLoop` which receives external events through the given `EventPort`.
cannam@134 619
cannam@134 620 ~EventLoop() noexcept(false);
cannam@134 621
cannam@134 622 void run(uint maxTurnCount = maxValue);
cannam@134 623 // Run the event loop for `maxTurnCount` turns or until there is nothing left to be done,
cannam@134 624 // whichever comes first. This never calls the `EventPort`'s `sleep()` or `poll()`. It will
cannam@134 625 // call the `EventPort`'s `setRunnable(false)` if the queue becomes empty.
cannam@134 626
cannam@134 627 bool isRunnable();
cannam@134 628 // Returns true if run() would currently do anything, or false if the queue is empty.
cannam@134 629
cannam@134 630 private:
cannam@134 631 EventPort& port;
cannam@134 632
cannam@134 633 bool running = false;
cannam@134 634 // True while looping -- wait() is then not allowed.
cannam@134 635
cannam@134 636 bool lastRunnableState = false;
cannam@134 637 // What did we last pass to port.setRunnable()?
cannam@134 638
cannam@134 639 _::Event* head = nullptr;
cannam@134 640 _::Event** tail = &head;
cannam@134 641 _::Event** depthFirstInsertPoint = &head;
cannam@134 642
cannam@134 643 Own<_::TaskSetImpl> daemons;
cannam@134 644
cannam@134 645 bool turn();
cannam@134 646 void setRunnable(bool runnable);
cannam@134 647 void enterScope();
cannam@134 648 void leaveScope();
cannam@134 649
cannam@134 650 friend void _::detach(kj::Promise<void>&& promise);
cannam@134 651 friend void _::waitImpl(Own<_::PromiseNode>&& node, _::ExceptionOrValue& result,
cannam@134 652 WaitScope& waitScope);
cannam@134 653 friend class _::Event;
cannam@134 654 friend class WaitScope;
cannam@134 655 };
cannam@134 656
cannam@134 657 class WaitScope {
cannam@134 658 // Represents a scope in which asynchronous programming can occur. A `WaitScope` should usually
cannam@134 659 // be allocated on the stack and serves two purposes:
cannam@134 660 // * While the `WaitScope` exists, its `EventLoop` is registered as the current loop for the
cannam@134 661 // thread. Most operations dealing with `Promise` (including all of its methods) do not work
cannam@134 662 // unless the thread has a current `EventLoop`.
cannam@134 663 // * `WaitScope` may be passed to `Promise::wait()` to synchronously wait for a particular
cannam@134 664 // promise to complete. See `Promise::wait()` for an extended discussion.
cannam@134 665
cannam@134 666 public:
cannam@134 667 inline explicit WaitScope(EventLoop& loop): loop(loop) { loop.enterScope(); }
cannam@134 668 inline ~WaitScope() { loop.leaveScope(); }
cannam@134 669 KJ_DISALLOW_COPY(WaitScope);
cannam@134 670
cannam@134 671 private:
cannam@134 672 EventLoop& loop;
cannam@134 673 friend class EventLoop;
cannam@134 674 friend void _::waitImpl(Own<_::PromiseNode>&& node, _::ExceptionOrValue& result,
cannam@134 675 WaitScope& waitScope);
cannam@134 676 };
cannam@134 677
cannam@134 678 } // namespace kj
cannam@134 679
cannam@134 680 #include "async-inl.h"
cannam@134 681
cannam@134 682 #endif // KJ_ASYNC_H_