[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Passing object references
Passing object references
Sun, 15 Dec 2002 04:16:09 +0100
I thought a bit about passing object handles from one task to another, and I
think that the previous proposal (which actually came from me and Neal)
lacked a bit:
* There was still one notification message from the server to the client.
* It was not optimized for the common case (synchronization between A and B
is implied if an RPC is sent afterwards that uses the object handle).
* It was not complete: If two threads in the task send the same reference to
another task B, server S can not tell which handle reception from B
belongs to which thread in A, so the notifications can not be mapped to
the correct caller.
So I started to attempt to construct a protocol from grounds up, writing down
the preconditions, requirements, and then tried to deduce how the protocol
must look like.
Well, that's how I started but I also added a good deal of intuition and
basic assumptions into it. The result is presented below. If you look
careful at it, then you will see that it is just another variation on the
auth protocol, and that makes me feel good, because it shows that we are
dealing with the same basic problem here.
We have: Server S, providing object O. Task A has a reference to O, O_A.
It wants to move (or copy, I am not interested in this difference here) a
reference to task B. After the process, task B should have a reference O_B
to the object O.
Constraints: There is no mutual trust between each two of S, A and B. In
fact, that constraint is already too tight, depending on how you define
trust. However, the following is meant: S does not trust A or B at all.
In particular, it will not send blocking messages [ideally only reply
messages] to them, and it will not take A's or B's word for which task gets
another reference - A will have to announce to S that B should get a
reference, but it will not actually be created until B acknowledges its
reception (to avoid that A can hide references in other - possibly
privileged - tasks without their consent). Furthermore, B doesn't trust A:
It should be possible for B to use the object reference from A without
further getting in contact with A (using the object reference might require
prior contact to S - but using the object at all requires contact to S, so
that's ok). And, A doesn't trust B: So it must be possible for A to find
out the status of the reference passing without consulting B.
There is also a synchronization requirement: Task A must be able to find out
when and if task B actually received the reference for real, so it can exit
safely. Furthermore, A must be able to cancel a pending operation, for
example if B doesn't cooperate for some reason. This must be done without
help from B for trust issues.
It's pretty clear now that what must happen is that A sends a message to S,
then to B, and then to S. B must receive the message from A, and then send
a message to S. Here is the protocol in detail:
1. Task A sends a message to S to initiate the reference passing operation.
Task A tells S which reference (O_A) it wants to move to which task (B),
and if it wants to sunchronize with handle reception in B (flag W for wait).
The server will return a transaction number T_A, which is unique to a
task, and makes a transaction record (O, A, T_A, B, W) in the server.
Note: The transaction number has the same job as the rendezvous port in
2a. Now task A sends the message to B it wants to send. This can be a simple
message (without reply), or a normal message with a blocking receive.
In the message, all send rights are represented by (S, T_A).
2b. If A wants to synchronize with handle reception (W flag set), it can
sent a message to S which blocks until the handle was received by B
(the transaction record will tell). (Optionally: once that happens,
the transaction record will be removed before replying success to A.
Note: This will only happen if the message in 2a was not a normal reply
message. In a normal reply message, success from B means that all handles
that B was interested in have been successfully received, so no
explicit synchronization is necessary. This is the common case!
2c. Task A sends a message to S to destroy the transaction record T_A.
Note: Optionally, this can be automatic if there is a successful
synchronization (and only on synchronization failure or without
explicit synchronization this step is necessary).
Note: This is analogeous to the deallocation of the rendezvous port.
Note: This step is important! If you don't do that, either unused
transaction records can pile up (if B is simply not interested in receiving
them) or transaction numbers can be reused too early and confuse A
(although this is very unlikely if you choose a 32 bit number carefully).
3a. Task B receives a message from B. For each handle it wants to receive,
it sends a message to S with (S, A, T_A). The server S will then look
up the transaction record, and create the object handle O_B for B, which
it will return. Before returning, it checks the W flag: If it is not
set, A is not interested in synchronization, so S removes the transaction
record immediately. Otherwise it will just set a flag internally that
means that the handle was received. If there are pending synchronization
requests, they are woken up (they will see the internal flag, and then
Furthermore: If A dies, all transaction records for A are deleted.
There is an RPC for A to destroy a transaction record.
Feel free to ask questions if I didn't make myself clear, or if there is
something I didn't provide enough rationale for. I think the above protocol
is pretty good, it allows for some optimizations if you are not really
interested in optimization, or if you only want to give B a certain time to
complete the reception of the handles. It only involves messages from A to
B, A to S and B to S, and B only needs to message S if it wants to receive
the handle, otherwise it can just ignore it.
 A real object (port) can't be used, as we need to copy a reference to
B, which means we need a reference passing protocol ;) - chicken and egg
problem. However, we _could_ use a transaction number in the auth protocol,
which is less transparentm, though.
 S might be given implicitely in T_A, just like it is implicit in O_A.
`Rhubarb is no Egyptian god.' GNU http://www.gnu.org address@hidden
Marcus Brinkmann The Hurd http://www.gnu.org/software/hurd/
- Passing object references,
Marcus Brinkmann <=