diff --git a/runtime-rpc/src/main/java/org/capnproto/RpcState.java b/runtime-rpc/src/main/java/org/capnproto/RpcState.java index 7cc1e02..55be7b2 100644 --- a/runtime-rpc/src/main/java/org/capnproto/RpcState.java +++ b/runtime-rpc/src/main/java/org/capnproto/RpcState.java @@ -1939,10 +1939,10 @@ final class RpcState { // We resolved to some other RPC capability hosted by the same peer. var promise = replacement.whenMoreResolved(); if (promise != null) { - var other = (PromiseClient)replacement; + var other = (PromiseClient) replacement; while (other.resolutionType == ResolutionType.MERGED) { replacement = other.cap; - other = (PromiseClient)replacement; + other = (PromiseClient) replacement; assert replacement.getBrand() == replacementBrand; } @@ -1958,14 +1958,11 @@ final class RpcState { resolutionType = ResolutionType.REMOTE; } } + else if (replacement.isNull() || replacement.isError()) { + resolutionType = ResolutionType.BROKEN; + } else { - if (replacementBrand == NULL_CAPABILITY_BRAND - || replacementBrand == BROKEN_CAPABILITY_BRAND) { - resolutionType = ResolutionType.BROKEN; - } - else { - resolutionType = ResolutionType.REFLECTED; - } + resolutionType = ResolutionType.REFLECTED; } assert isResolved(); diff --git a/runtime/src/main/java/org/capnproto/Capability.java b/runtime/src/main/java/org/capnproto/Capability.java index ee02617..ff8b593 100644 --- a/runtime/src/main/java/org/capnproto/Capability.java +++ b/runtime/src/main/java/org/capnproto/Capability.java @@ -7,6 +7,9 @@ import java.util.concurrent.CompletionStage; public final class Capability { + static final Object NULL_CAPABILITY_BRAND = new Object(); + static final Object BROKEN_CAPABILITY_BRAND = new Object(); + static class BuilderContext { CapTableBuilder capTable; } @@ -645,15 +648,15 @@ public final class Capability { } public static ClientHook newBrokenCap(String reason) { - return newBrokenClient(reason, false, ClientHook.BROKEN_CAPABILITY_BRAND); + return newBrokenClient(reason, false, BROKEN_CAPABILITY_BRAND); } public static ClientHook newBrokenCap(Throwable exc) { - return newBrokenClient(exc, false, ClientHook.BROKEN_CAPABILITY_BRAND); + return newBrokenClient(exc, false, BROKEN_CAPABILITY_BRAND); } public static ClientHook newNullCap() { - return newBrokenClient(RpcException.failed("Called null capability"), true, ClientHook.NULL_CAPABILITY_BRAND); + return newBrokenClient(RpcException.failed("Called null capability"), true, NULL_CAPABILITY_BRAND); } private static ClientHook newBrokenClient(String reason, boolean resolved, Object brand) { @@ -800,6 +803,11 @@ public final class Capability { public CompletableFuture whenMoreResolved() { return this.promiseForClientResolution.copy(); } + + @Override + public Object getBrand() { + return null; + } } public static final class CapabilityServerSet { diff --git a/runtime/src/main/java/org/capnproto/ClientHook.java b/runtime/src/main/java/org/capnproto/ClientHook.java index d21156b..d04e125 100644 --- a/runtime/src/main/java/org/capnproto/ClientHook.java +++ b/runtime/src/main/java/org/capnproto/ClientHook.java @@ -5,9 +5,6 @@ import java.util.concurrent.CompletableFuture; public interface ClientHook { - Object NULL_CAPABILITY_BRAND = new Object(); - Object BROKEN_CAPABILITY_BRAND = new Object(); - /** * Start a new call, allowing the client to allocate request/response objects as it sees fit. * This version is used when calls are made from application code in the local process. @@ -56,9 +53,7 @@ public interface ClientHook { discover when a capability it needs to marshal is one that it created in the first place, and therefore it can transfer the capability without proxying. */ - default Object getBrand() { - return NULL_CAPABILITY_BRAND; - } + Object getBrand(); /** * Repeatedly calls whenMoreResolved() until it returns nullptr. @@ -75,14 +70,14 @@ public interface ClientHook { * reading a null pointer out of a Cap'n Proto message. */ default boolean isNull() { - return getBrand() == NULL_CAPABILITY_BRAND; + return getBrand() == Capability.NULL_CAPABILITY_BRAND; } /** * Returns true if the capability was created by newBrokenCap(). */ default boolean isError() { - return getBrand() == BROKEN_CAPABILITY_BRAND; + return getBrand() == Capability.BROKEN_CAPABILITY_BRAND; } /**