[Top][All Lists]

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

Re: multiple capabilities in a single RPC

From: Marcus Brinkmann
Subject: Re: multiple capabilities in a single RPC
Date: Tue, 18 Jan 2005 20:41:41 +0100
User-agent: Wanderlust/2.10.1 (Watching The Wheels) SEMI/1.14.6 (Maruoka) FLIM/1.14.6 (Marutamachi) APEL/10.6 Emacs/21.3 (i386-pc-linux-gnu) MULE/5.0 (SAKAKI)

At Mon, 17 Jan 2005 18:53:08 +0000,
> We need an interface to allow multiple capability objects to be
> accessed by a single RPC stub.

Yes.  As we discussed extensively in IRC, the choices in designing
this are pretty narrow, and we have to limit ourselves to some
reasonable constraints (like, both objects must be handled by the same
bucket, etc).

Given such constraints, the actual solution is actually pretty simple,
and I hacked up a patch that may do it.  Of course I was too lazy to
even compile it.  But if you are lucky there are only typos and no
semantical problems ;)

This is the interface I settled on:

/* Start to use the capability with the handle CAP within the RPC
   operation CTX, using CAP_USE to store information that allows to
   end the use of CAP with hurd_cap_ctx_end_cap_use.  If SAME_CLASS is
   true, an error is returned if CAP is not of the same class as
   CTX->CAP.  On successful return, CAP_USE->OBJ will be locked.  */
error_t hurd_cap_ctx_start_cap_use (hurd_cap_rpc_context_t ctx,
                                    hurd_cap_handle_t cap,
                                    struct hurd_cap_ctx_cap_use *cap_use,
                                    bool same_class);

/* End the use of the object CAP_USE->OBJ, which must be locked.  */
void hurd_cap_ctx_end_cap_use (struct hurd_cap_ctx_cap_use *cap_use);

Having the objects locked makes absolutely certain that you must have
no other object locked at the time you call either function, or you
risk dead-locks.

The actual object is then in CAP_USE->obj.

SAME_CLASS is useful to avoid overhead when we can tell early that the
client is violating our protocol.  As this is the common case, I think
it may be useful.  In contrast to what I said earlier, I already
included an implementation for the case that the classes are
different.  It turned out to be a small thing.

The #if mess in the code is just there to show where the code differs
from the code in bucket-manage-mt.c.  This information will allow us
to quickly decide if and how we can refactor the code.  But first we
should probably try it out :)

There are probably some error values which should be changed, because
they are more suitable for the demuxer internals than for an actual
user.  I am thinking about the ECAP_* error codes.

Now, I envision that you use it like this:

foo (object1, object2)
  unlock (object1);

  start_cap_use (object2);

  /* object2 is locked now.  Do something with it.  */

  end_cap_use (object2);

  lock (object1);

  /* Do something.  */

  /* object1 must be locked before returning.  */

Note that other RPCs are allowed on object1 in the window where it is
unlocked.  If you need to change object2 after using object1, you need
to delay the end_cap_use and unlock/lock object2 appropriately.

You can not lock two objects at the same time, unless you define a
locking hierarchy for all the objects in the set, or find some other
dead-lock-avoidance strategy.

Experimental patch attached.


Attachment: cap-use.patch
Description: Binary data

reply via email to

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