#pragma once #include namespace workerd { // A membrane applied which detects when no capabilities are held any longer, at which point it // fulfills a fulfiller. // // TODO(cleanup): This is generally useful, should it be part of capnp? class CompletionMembrane final: public capnp::MembranePolicy, public kj::Refcounted { public: explicit CompletionMembrane(kj::Own> doneFulfiller) : doneFulfiller(kj::mv(doneFulfiller)) {} ~CompletionMembrane() noexcept(false) { doneFulfiller->fulfill(); } kj::Maybe inboundCall( uint64_t interfaceId, uint16_t methodId, capnp::Capability::Client target) override { return kj::none; } kj::Maybe outboundCall( uint64_t interfaceId, uint16_t methodId, capnp::Capability::Client target) override { return kj::none; } kj::Own addRef() override { return kj::addRef(*this); } void reject(kj::Exception&& e) { doneFulfiller->reject(kj::mv(e)); } private: kj::Own> doneFulfiller; }; // A membrane which revokes when some Promise is fulfilled. // // TODO(cleanup): This is generally useful, should it be part of capnp? class RevokerMembrane final: public capnp::MembranePolicy, public kj::Refcounted { public: explicit RevokerMembrane(kj::Promise promise): promise(promise.fork()) {} kj::Maybe inboundCall( uint64_t interfaceId, uint16_t methodId, capnp::Capability::Client target) override { return kj::none; } kj::Maybe outboundCall( uint64_t interfaceId, uint16_t methodId, capnp::Capability::Client target) override { return kj::none; } kj::Own addRef() override { return kj::addRef(*this); } kj::Maybe> onRevoked() override { return promise.addBranch(); } private: kj::ForkedPromise promise; }; } // namespace workerd