Hi Denis,
This means, the Rpc_objects can communicate, if they are managed by the same Entrypoint, but not if they are in different Entrypoints. Just out of curiosity: Can I delegate a capability from one Entrypoint to another?
I am not sure what you mean by "communicate" exactly here. The important point is that core's RAM session tried to look up another RAM session by using a the capability it received (as argument to the transfer-quota call) as key. The operation to look up an RPC object by a given capability is provided by the entrypoint (via the 'apply' method). However, the entrypoint knows only those RPC objects that it manages. So when presented with a capability that refers to an RPC object managed by some other entrypoint (in your case, the entrypoint living in your "random" program), it finds no matching RPC object among its managed objects.
I think, the child constructor created an Rpc_object<Parent>, which is managed by the child's Entrypoint. Then the Rpc_object<Parent> called an RPC method from my Rpc_object<Ram_session>, which also is managed by this Entrypoint. Thus, the Entrypoint blocked on the remote procedure call to Rpc_objcet<Ram_session> waiting for itself to finish the call from Rpc_object<Ram_session>. The Rpc_object<Ram_session> needs to use this Entrypoint, but it was blocked. Thus, it went waiting for the Entrypoint.
Exactly!
Now Rpc_object<Parent> is waiting for Rpc_object<Ram_session> and vice vera => deadlock.
Please correct me, if I am wrong :)
Your analysis is flawless. :-)
For this exact reason, the Genode::Child constructor takes the RAM session (to be used locally to initialize the child) and RAM-session capability as two distinct arguments instead of internally creating a Ram_session_client object with the capability.
Cheers Norman