// Copyright (c) 2017-2022 Cloudflare, Inc. // Licensed under the Apache 2.0 license found in the LICENSE file or at: // https://opensource.org/licenses/Apache-2.0 #pragma once #include #include namespace workerd { class XThreadNotifier final: public kj::AtomicRefcounted { // Class encapsulating the ability to notify a waiting thread from other threads. // // TODO(cleanup): Can this be consolidated with wait-list.h? // // TODO(cleanup): This could be a lot simpler if only it were possible to cancel // an executor.executeAsync() promise from an arbitrary thread. Then, if the inspector // session was destroyed in its thread while a cross-thread notification was in-flight, it // could cancel that notification directly. public: static inline kj::Own create() { return kj::atomicRefcounted(); } XThreadNotifier(): paf(kj::newPromiseAndCrossThreadFulfiller()) {} kj::Promise awaitNotification() { auto promise = kj::mv(paf.lockExclusive()->promise); co_await promise; auto lockedPaf = paf.lockExclusive(); auto nextPaf = kj::newPromiseAndCrossThreadFulfiller(); lockedPaf->promise = kj::mv(nextPaf.promise); lockedPaf->fulfiller = kj::mv(nextPaf.fulfiller); } void notify() const { paf.lockExclusive()->fulfiller->fulfill(); } private: kj::MutexGuarded> paf; }; } // namespace workerd