l4-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

object management and IPC a bit more formal


From: Marcus Brinkmann
Subject: object management and IPC a bit more formal
Date: Mon, 5 May 2003 20:36:30 +0200
User-agent: Mutt/1.5.3i

Hi,

here what I proposed in a bit more formal way.  Hopefully this helps.

Thanks,
Marcus


Tasks and Threads
=================

The version part of the thread ID is used as the PID.

The thread ID part is split into a subsystem ID and a thread ID.

Any task can request a reference and task death notification to any
other (existing) PID.  This prevents the PID from being reused until
the reference is released (for example in response to a task
death notification).


Object Management and IPC
=========================

A server S provides objects.  Objects are identified to clients by the
server that provides them and a server-wide unique object ID.  Clients
are identified to the server by their thread ID (and thus by their
PID).  L4 guarantees that the sender's thread ID in the message is
correct.

Over the whole time, S keeps a reference for A's PID in the task
server to ensure that it is always the same client task sending the
messages.  S also receives death notification for A to clean up the
pending references and transaction records.

Over the whole time, A keeps a reference for S's PID in the task
server to ensure that it is always sending the messages to the same
server.  A also receives death notification for S so that it can
release the reference for the PID of S and record that the server's
object IDs are now invalid (dead name).


Server side
-----------

(The types are not meant for real, but just for illustration.)

struct server_object
{
  object_id_t id;
  void *object_data;
  struct
    {
      int references;
      pid_t user;
      struct
        {
          pid_t receiving_user;
          bool received;
        } transactions[];
    } user[];
};

struct server_object *lookup_server_object (object_id_t id);


This is how the server receives a message:

1. Receive message.
2. (If this is the last thread in the pool, create a new receiver.)
3. server_object_t obj = lookup_server_object (msg->id);
4. Search in OBJ if there is a user with the PID of the sender.
5. If yes, then process the message.
6. Goto 1.


User side
---------

struct user_object
{
  thread_t server;
  object_id_t oid;
};

If the lower bits of the thread id part of SERVER are 0, then the
client sends the message to server + the processor number (shifted to
the thread id position).  Otherwise it just sends it to SERVER.

OID is just as the first argument in the message.


Moving Object Handles
---------------------

This is how a client A can give B an object handle for an object
provided by server S.

Over the whole time, S keeps a reference to A's PID, just because A is
a client of S (see above).

Over the whole time, B keeps a reference to A's PID, not only because
A is a client of B, but also to ensure that it gets the handle that
was granted by A and not by any other task.

Over the whole time, A keeps a reference to S's PID, not just because
A is a client of S, but also to ensure that B contacts the same server
S as A did.

Over the whole time, A keeps a reference to B's PID, not just because
A is a client of B, but also to ensure that the same B that A granted
the object handle receives it from S.


Here is the synchronous version (A blocks on B):

1. A requests a transaction record T for B from S.  T is kept in S
along with A's other references to the object.  T is removed either
when A requests it or if A dies.  T is only valid for B.

2. A sends the server thread ID S and the transaction record T to B.

3. B sends the PID of A and the transaction record to S.

4. S takes a reference to B's PID and replies to B's message (from
   step 3) with the object ID.

5. B takes a reference to S's PID and replies to A's message (from
   step 2) signalling success.  (If this fails, it should destroy the
   handle it got from S, and releases its reference to S's PID, as A
   probably didn't have a chance to protect S's PID integrity).

6. A sends the server the transaction record T to get it destroyed.

7. S destroys the transaction record.

8. A can now safely release its own handle to the object, as B has
   established its own, independent connection.  A can also release
   its connection to B.

Note that only A can guarantee that really S and B establish a
connection, and not S with some other rogue task B' (which grapped the
PID of B) or some rogue task S' with B (which grapped the server's
PID).  But as A provided S with B and B with S, it is the only one who
needs to care anyway.

Note that in this protocol S does not need to send (notification)
messages to either A nor B.

Note that if any of A, B and S fails to follow the protocol, they can
not do additional harm to any of the others.  Mutual trust is not
required.

The cost of this protocol is, beside the message from A to B (plus
reply), and the two messages to the task server (plus reply), three
messages (and their reply) to the server S.

If a message contains several handles, all handles could be processed
at once by allowing array forms of the server RPCs.


Here is the asynchronous version (A doesn't block on B):

1. - 4. As above.

5. B takes a reference to S's PID.

6. As above.  A special RPC or flag is used to let the RPC block in
   the server until B completed the transaction or it receives a task
   death notification for B (or S of course).

7. - 8. As above.

Note that A should always wait for B to complete (either by waiting
for B's reply, or by blocking in the server), because otherwise, if A
drops the connection to S prematurely, S might drop the transaction
record before B can accept it, or S might send to a rogue B' (which
stole the PID from B).

-- 
`Rhubarb is no Egyptian god.' GNU      http://www.gnu.org    address@hidden
Marcus Brinkmann              The Hurd http://www.gnu.org/software/hurd/
address@hidden
http://www.marcus-brinkmann.de/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]