Gary Cramblitt garycramblitt at comcast.net
Tue Nov 14 06:17:38 PST 2006

On Tuesday 14 November 2006 02:00, Havoc Pennington wrote:
> Gary Cramblitt wrote:
> >  If you send many such references,
> > you may need a way to "shorten" the names by providing an object
> > reference registry and pass integer IDs instead of Path Names.  Some
> > projects are proposing to use XAtom for this.
> This is not a good idea imo,
> 1) relative to everything else happening the size of the object path is
> probably not even measurable as a performance issue - it isn't a large
> fraction of the dbus message, and message size does not make a big
> performance difference anyway unless you're shoveling megabytes of data
> (in which case the megabytes of data presumably are not just object refs)
> 2) you can use a path like "/abcd" if you like, which is extremely short
> (though I'd advise a namespace instead, even say "/com/example/abcd" is
> plenty short). Or if you want integer IDs in-process then just track
> them and make the object path /com/example/1234 where 1234 = your
> integer id.
> 3) in real-world performance the X atom will be *much* worse than some
> extra bytes in dbus messages; it will mean talking to the X server (even
> round trips), and there is no way to delete old unused X atoms.
> For performance, the first worry should always be round trips, not size
> of messages. Sending and receiving a message involves all sorts of
> parsing, validating, context switching, etc.; this fixed overhead is
> almost all the work. As long as your message is under 1K or so (whatever
> the buffer size libdbus uses, don't remember), the number of read/write
> syscalls will be the minimum number. So shrinking the message will do
> one thing: *very* slightly speed up the memcpy()'s that happen, which
> are not the bottleneck anyway.

Thank you for your feedback Havoc.   I personally tend to agree with you.  The 
situation for object references is actually worse than I indicated.  In order 
to have a complete object reference, one must have

1.  The process that owns the object, i.e., the Bus Name.
2.  The object Path Name.
3.  (optionally) If the object has multiple interfaces, the Interface Name.

In the case of AT-SPI there are a few methods in the API that can return 
hundreds of object references.  For example, the children() method returns 
all the child screen elements (widgets) of a parent.  For a web browser, this 
could be hundreds of elements.  I tend to think these are "edge" cases 
however and we are prematurely optimizing.  I would like to see a working 
prototype first where we can measure performance and solve the few cases 
where message size becomes an issue.

It is interesting that you state XAtoms cannot be deleted once created.  I 
noticed that the XAtom API does not offer an explicit destroy method, but I 
had assumed one could simply XFree() them.  I guess I was wrong?

Anyway, some are proposing a home grown string registry instead of XAtom.

BTW, the motivation for a string registry is more than D-Bus performance.  
Memory consumption in the AT clients is also a concern.

> > 2.  Object lifetime and reference counting.  After passing an object
> > reference to another process via D-Bus, how do you know when the object
> > may be destroyed?  Typically, as is done in XPCOM, this is managed via
> > reference counting.  Trying to do reference counting over D-Bus is
> > challenging.
> s/challenging/totally insane/ (been there done that)
> What you want to do here is have explicit lifecycle policies on remote
> objects. Good ones include:
>   - stateless. like http, just have calls that don't require keeping
>     an object around beyond a single request.
>   - leases. Remote object times out and has to be recreated.
>   - explicit destroy. Users of a remote object must call a "destroy"
>     method.  (Best combined with a remote object implementation that
>     tracks when the object owner disappears without destroying, and
>     automatically cleans up. Otherwise crashed apps cause leaks. dbus
>     is designed to make this possible.)
> A frequent version of the third pattern is a register/unregister kind of
> metaphor; to use a given API you must "register" which allocates a set
> of resources specific to you and gives you a "registration ID" for
> referring to those resources. Many web services APIs, such as the
> Facebook one, use a model like this.
> You can then either time out registered clients that have not done
> anything lately, or you can monitor their presence on the bus and drop
> their resources if they vanish.

Unfortunately for Mohamed, he's trying to layer a generic component system on 
D-Bus, so your first two policies won't work.  In our case, we are trying to 
implement a specific API (AT-SPI).  Fortunately for us, most of the API fits 
the stateless policy.  Even if a client attempts to access an object that no 
longer exists and gets an error, it simply means the corresponding on-screen 
component is gone and the AT client doesn't need to worry about it anymore.

Unfortunately for us, there are a few methods in the AT-SPI that don't fit the 
stateless policy.  For example, there is method called getState() which 
returns a set of state flags for an on-screen component.  Unfortunately, it 
returns a StateSet object that then offers methods for comparing two 
StateSets, adding flags, or testing whether a specific flag is included in 
the set.  My personal opinion is this is an "over objectized" API that is 
fine in a CORBA environment but just wrong in a D-Bus messaging environment.  
I'd like to see the API changed to return a simple list of state flags, but 
I'm struggling against a community with a working implementation (Gnome) and 
attempting to port to a community with no working implementation (KDE).  In 
the end, we'll probably have to implement some sort of explicit destroy 
pattern as you suggest.

> Please post any questions you have and we'll try to help out, btw.

Count on it!  Thanks.

Gary Cramblitt (aka PhantomsDad)

More information about the dbus mailing list