RFC: Managing lifetime of objects on DBus

William Manley william.manley at youview.com
Fri Jun 17 11:42:40 PDT 2011


Hello all

I've been thinking about managing the lifetime of objects created in a
DBus server on behalf of a DBus client.  I've come up with a scheme
which I think is quite good and would appreciate comment in case I have
misunderstood some DBus concepts or made some oversight.  In addition,
if you'd be interested, it would be nice to make it a standard DBus
interface.  I think it complements org.freedesktop.DBus.ObjectManager.

My proposal is included below.  It is currently called Zinc.Managed as
"Zinc" is the code name for the TV set-top box middleware I am working
on at YouView.

Thanks

Will

> Zinc.Managed
> ============
>
> Zinc.Managed: Robust reference counted objects across DBus
>
> The existing standard DBus interface org.freedesktop.DBus.ObjectManager is
> designed to manage the lifetimes of proxies to remote DBus objects, such that
> when an object comes into existance a proxy can be created, and when the
> (remote) object goes away the proxy can be removed.  However, no standard
> solution is provided for the mirror image problem of managing the lifetime of
> server-side objects that are created on behalf of clients.  Managing the
> lifetime in this instance means deleting the object in the server side once the
> client is finished with it.
>
> We wish to do this in a robust, asynchronous and minimally chatty way so we
> use a reference count which can be explicitly reduced by a client in addition
> to watching for clients dropping off the bus.
>
> An additional interface is attached to any objects that are to be "Managed" to
> allow the client to explicitly communicate that it is finished with the object:
>
>     interface Zinc.Managed {
>         void DropRef(uint32 n) noreply;
>         void AddRef() noreply;
>     };
>
> 1) Every time an object is returned to a client from a server the reference
>    count for that path/client bus name is incremented in the server.
> 2) Whenever the client receives an object path the reference count for that
>    path/server bus name is incremented
> 3) Once the client is finished with this object it calls Zinc.Managed.DropRef
>    on that object giving the reference count that it has accumulated
> 4) If all the client references to an object have been dropped, the server can
>    choose to remove the object from the bus and potentially delete it.
> 5) In addition, to cope with unclean client exits, the server should register
>    for NameOwnerChanged events for clients that own Managed objects.  The
>    server should reset the reference count for those clients when the client
>    drops off the bus
>
>
> As far as I can tell this scheme doesn't suffer the same race condition as a
> non-reference counted implementation.  In particular, it is safe when a client
> drops all references to a remote object while the server is in the process of
> returning an additional reference to the same object.
>
> Example
> =======
>
>     interface Zinc.AnimalCompetition {
>         DBusPath CreateCow();
>         DBusPath GetBiggestCow();
>     }
>
> Client pseudocode
> -----------------
>
>     main() {
>         AnimalCompetitionProxy acp("server.busname", "/Zinc/AnimalCompetition");
>         CowProxy* cow = acp.createCowProxy()
>         // Do some stuff
>         delete cow;
>     }
>
> DBus traffic (in ASCII pseudo-bustle[3] format)
> -----------------------------------------------
>
>                                           :1.1     server.busname    o.f.DBus
>                                             |             |             |
> /Zinc/AnimalCompetition                     |             |             |
> Zinc.AnimalCompetition.CreateCow()          |------------>|---\         |
>                                             |             |   |         |
> /Zinc/AnimalCompetition                     |             |   |         |
> Zinc.AnimalCompetition.CreateCow(/daisy)    |<------------|---/         |
>                                             |             |             |
> /                                           |             |             |
> o.f.DBus.AddMatch(NameOwnerChanged=:1.1)    |             |------------>|
>                                             |             |             |
> /                                           |             |             |
> o.f.DBus.NameHasOwner(":1.1")               |             |------------>|---\
>                                             |             |             |   |
> /                                           |             |             |   |
> o.f.DBus.NameHasOwner(true)                 |             |<------------|---/
>                                             |             |             |
> /daisy                                      |             |             |
> Zinc.Managed.DropRef(1)                     |------------>|             |
>                                             |             |             |
>
> The server can decrement the refcount for a client in response to an explicit
> DropRef, or drop the refcount entirely for a negative response to NameHasOwner
> or a NameOwnerChangedEvent (indicating that ":1.1" has exited).  The server can
> implement this entirely asynchronously without blocking or race conditions (as
> it is in my implementation[4]).
>
> Sending object paths to other processes
> =======================================
> The purpose of AddRef is to allow passing ownership of Managed objects between
> client processes.  A client can send a path to another client with a DBus method
> call.  The second client must then call AddRef() on that object path before
> replying to the first client process.  The two clients are then equal partners in
> ownership of that remote object.
>
> Managed and signals
> ===================
> Because it is not possible to tell who might receive a broadcast signal
> containing a DBus path, the reference count should not be incremented in this
> case.  If clients wish to take ownership of paths recieved in a broadcast with
> signals they must call AddRef explicitly on these object.  Care should be taken
> when doing this as it is potentially racy.
>
> [1] YouView (http://www.youview.com/).  We are building a set top box with a
>     multi-process architecture with DBus for IPC.
>
> [2] We recognise that the client has finished with an object when, either it
>     explicitly says so, or it exits.
>
> [3] Bustle is a really cool and useful tool.  Thanks!
>
> [4] A fork of DBus-C++ that I am preparing for publication
>
>
>


This transmission contains information that may be confidential and contain personal views which are not necessarily those of YouView TV Ltd. YouView TV Ltd (Co No:7308805) is a limited liability company registered in England and Wales with its registered address at B6, Ground Floor Broadcast Centre, 201 Wood Lane, London, UK, W12 7TP.

For details see our web site at http://www.youview.com.




More information about the dbus mailing list