handleDisembargo. NB future evaluation order needs work
This commit is contained in:
parent
c938938808
commit
6bd1411c26
1 changed files with 60 additions and 1 deletions
|
@ -486,8 +486,67 @@ final class RpcState {
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleDisembargo(RpcProtocol.Disembargo.Reader disembargo) {
|
void handleDisembargo(RpcProtocol.Disembargo.Reader disembargo) {
|
||||||
}
|
var ctx = disembargo.getContext();
|
||||||
|
switch (ctx.which()) {
|
||||||
|
case SENDER_LOOPBACK:
|
||||||
|
var target = getMessageTarget(disembargo.getTarget());
|
||||||
|
if (target == null) {
|
||||||
|
// Exception already reported.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (; ; ) {
|
||||||
|
var resolved = target.getResolved();
|
||||||
|
if (resolved == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
target = resolved;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert target.getBrand() == RpcState.this : "'Disembargo' of type 'senderLoopback' sent to an object that does not point back to the sender.";
|
||||||
|
if (target.getBrand() != this) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var embargoId = ctx.getSenderLoopback();
|
||||||
|
|
||||||
|
// TODO run this later...
|
||||||
|
if (isDisconnected()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var rpcTarget = (RpcClient) target;
|
||||||
|
var message = connection.newOutgoingMessage(1024);
|
||||||
|
var builder = message.getBody().initAs(RpcProtocol.Message.factory).initDisembargo();
|
||||||
|
var redirect = rpcTarget.writeTarget(builder.initTarget());
|
||||||
|
// Disembargoes should only be sent to capabilities that were previously the subject of
|
||||||
|
// a `Resolve` message. But `writeTarget` only ever returns non-null when called on
|
||||||
|
// a PromiseClient. The code which sends `Resolve` and `Return` should have replaced
|
||||||
|
// any promise with a direct node in order to solve the Tribble 4-way race condition.
|
||||||
|
// See the documentation of Disembargo in rpc.capnp for more.
|
||||||
|
if (redirect == null) {
|
||||||
|
assert false: "'Disembargo' of type 'senderLoopback' sent to an object that does not appear to have been the subject of a previous 'Resolve' message.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
builder.getContext().setReceiverLoopback(embargoId);
|
||||||
|
message.send();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RECEIVER_LOOPBACK:
|
||||||
|
var embargo = embargos.find(ctx.getReceiverLoopback());
|
||||||
|
if (embargo == null) {
|
||||||
|
assert false: "Invalid embargo ID in 'Disembargo.context.receiverLoopback'.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
assert embargo.disembargo != null;
|
||||||
|
embargo.disembargo.complete(null);
|
||||||
|
embargos.erase(ctx.getReceiverLoopback(), embargo);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert false: "Unimplemented Disembargo type. " + ctx.which();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
private List<Integer> writeDescriptors(ClientHook[] capTable, RpcProtocol.Payload.Builder payload, List<Integer> fds) {
|
private List<Integer> writeDescriptors(ClientHook[] capTable, RpcProtocol.Payload.Builder payload, List<Integer> fds) {
|
||||||
if (capTable.length == 0) {
|
if (capTable.length == 0) {
|
||||||
return List.of();
|
return List.of();
|
||||||
|
|
Loading…
Reference in a new issue