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