...on a remote capability foo, and there are no other reference to foo, you get a deadlock, because after constructing the cap table for the message:
The rpc subsystem assumes the Params struct owns the reference you just passed it, so wants to decrement it.
Doing so drops its refcount to 0, so it calls .Release() on the client.
.Release() waits for there to be no outstanding calls, which will never happen, because it was called by code sending foo.Method.
This is arguably a bug in the application, the solution to which is just to do p.SetFoo(foo.AddRef()). But it's sad that the failure mode for this mistake is a deadlock; it would be nice to try to detect this and panic or something instead.
I think we could do a check for this inside Client.SendCall, just by looping over the CapTable and checking that nothing is pointer-equal to the receiver.
There's a deadlock footgun that I hit while writing tests for #213. Roughly, if you do:
...on a remote capability
foo
, and there are no other reference tofoo
, you get a deadlock, because after constructing the cap table for the message:.Release()
on the client..Release()
waits for there to be no outstanding calls, which will never happen, because it was called by code sendingfoo.Method
.This is arguably a bug in the application, the solution to which is just to do
p.SetFoo(foo.AddRef())
. But it's sad that the failure mode for this mistake is a deadlock; it would be nice to try to detect this and panic or something instead.