Skip to content
File

Blob: src/workerd/util/xthreadnotifier.h

cpp46 lines
1// Copyright (c) 2017-2022 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4 
5#pragma once
6 
7#include <kj/async.h>
8#include <kj/mutex.h>
9 
10namespace workerd {
11 
12class XThreadNotifier final: public kj::AtomicRefcounted {
13 // Class encapsulating the ability to notify a waiting thread from other threads.
14 //
15 // TODO(cleanup): Can this be consolidated with wait-list.h?
16 //
17 // TODO(cleanup): This could be a lot simpler if only it were possible to cancel
18 // an executor.executeAsync() promise from an arbitrary thread. Then, if the inspector
19 // session was destroyed in its thread while a cross-thread notification was in-flight, it
20 // could cancel that notification directly.
21 public:
22 static inline kj::Own<XThreadNotifier> create() {
23 return kj::atomicRefcounted<XThreadNotifier>();
24 }
25 
26 XThreadNotifier(): paf(kj::newPromiseAndCrossThreadFulfiller<void>()) {}
27 
28 kj::Promise<void> awaitNotification() {
29 auto promise = kj::mv(paf.lockExclusive()->promise);
30 co_await promise;
31 auto lockedPaf = paf.lockExclusive();
32 auto nextPaf = kj::newPromiseAndCrossThreadFulfiller<void>();
33 lockedPaf->promise = kj::mv(nextPaf.promise);
34 lockedPaf->fulfiller = kj::mv(nextPaf.fulfiller);
35 }
36 
37 void notify() const {
38 paf.lockExclusive()->fulfiller->fulfill();
39 }
40 
41 private:
42 kj::MutexGuarded<kj::PromiseCrossThreadFulfillerPair<void>> paf;
43};
44 
45} // namespace workerd