Commit 743e7cec authored by Kenton Varda's avatar Kenton Varda

Add a concept of membrane trees, needed in Sandstorm.

parent 6cfe2aab
......@@ -321,13 +321,15 @@ public:
static kj::Own<ClientHook> wrap(ClientHook& cap, MembranePolicy& policy, bool reverse) {
if (cap.getBrand() == MEMBRANE_BRAND) {
auto& otherMembrane = kj::downcast<MembraneHook>(cap);
if (otherMembrane.policy.get() == &policy && otherMembrane.reverse == !reverse) {
auto& rootPolicy = policy.rootPolicy();
if (&otherMembrane.policy->rootPolicy() == &rootPolicy &&
otherMembrane.reverse == !reverse) {
// Capability that passed across the membrane one way is now passing back the other way.
// Unwrap it rather than double-wrap it.
Capability::Client unwrapped(otherMembrane.inner->addRef());
return ClientHook::from(
reverse ? policy.importInternal(kj::mv(unwrapped))
: policy.exportExternal(kj::mv(unwrapped)));
reverse ? rootPolicy.importInternal(kj::mv(unwrapped), *otherMembrane.policy, policy)
: rootPolicy.exportExternal(kj::mv(unwrapped), *otherMembrane.policy, policy));
}
}
......@@ -339,13 +341,15 @@ public:
static kj::Own<ClientHook> wrap(kj::Own<ClientHook> cap, MembranePolicy& policy, bool reverse) {
if (cap->getBrand() == MEMBRANE_BRAND) {
auto& otherMembrane = kj::downcast<MembraneHook>(*cap);
if (otherMembrane.policy.get() == &policy && otherMembrane.reverse == !reverse) {
auto& rootPolicy = policy.rootPolicy();
if (&otherMembrane.policy->rootPolicy() == &rootPolicy &&
otherMembrane.reverse == !reverse) {
// Capability that passed across the membrane one way is now passing back the other way.
// Unwrap it rather than double-wrap it.
Capability::Client unwrapped(otherMembrane.inner->addRef());
return ClientHook::from(
reverse ? policy.importInternal(kj::mv(unwrapped))
: policy.exportExternal(kj::mv(unwrapped)));
reverse ? rootPolicy.importInternal(kj::mv(unwrapped), *otherMembrane.policy, policy)
: rootPolicy.exportExternal(kj::mv(unwrapped), *otherMembrane.policy, policy));
}
}
......@@ -489,11 +493,13 @@ Capability::Client MembranePolicy::exportInternal(Capability::Client internal) {
ClientHook::from(kj::mv(internal)), addRef(), false));
}
Capability::Client MembranePolicy::importInternal(Capability::Client internal) {
Capability::Client MembranePolicy::importInternal(
Capability::Client internal, MembranePolicy& exportPolicy, MembranePolicy& importPolicy) {
return kj::mv(internal);
}
Capability::Client MembranePolicy::exportExternal(Capability::Client external) {
Capability::Client MembranePolicy::exportExternal(
Capability::Client external, MembranePolicy& importPolicy, MembranePolicy& exportPolicy) {
return kj::mv(external);
}
......
......@@ -144,13 +144,22 @@ public:
// itself was originally returned by the default implementation of exportInternal(), in which
// case importInternal() is called instead.
virtual Capability::Client importInternal(Capability::Client internal);
virtual MembranePolicy& rootPolicy() { return *this; }
// If two policies return the same value for rootPolicy(), then a capability imported through
// one can be exported through the other, and vice versa. `importInternal()` and
// `exportExternal()` will always be called on the root policy, passing the two child policies
// as parameters. If you don't override rootPolicy(), then the policy references passed to
// importInternal() and exportExternal() will always be references to *this.
virtual Capability::Client importInternal(
Capability::Client internal, MembranePolicy& exportPolicy, MembranePolicy& importPolicy);
// An internal capability which was previously exported is now being re-imported, i.e. a
// capability passed out of the membrane and then back in.
//
// The default implementation simply returns `internal`.
virtual Capability::Client exportExternal(Capability::Client external);
virtual Capability::Client exportExternal(
Capability::Client external, MembranePolicy& importPolicy, MembranePolicy& exportPolicy);
// An external capability which was previously imported is now being re-exported, i.e. a
// capability passed into the membrane and then back out.
//
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment