D-Bus is killing me
simon.mcvittie at collabora.co.uk
Sun Dec 17 19:43:09 PST 2006
On Mon, 18 Dec 2006 at 02:15:48 +0000, Mystilleef wrote:
> I figured the concepts were the same and I didn't want to write yet
> another D-Bus for intra-process communication specifically for my app.
Sorry, my use of the term "intra-process" may have been somewhat unclear.
I should have said "within the same process". Within a single process you
don't need D-Bus, you can just call functions/methods directly; if you're
putting effort into making sure there is only ever a single process for
your app (as you seem to be), then it's guaranteed that any "instance" you
want to communicate with is in-process, so you never need to make calls to
other instances that *aren't* in-process and everything is simple.
(By "instance" I assume you mean an instance of some particular object,
like a window or a document? I'd just have a global list of windows...)
You can still provide a D-Bus interface if you want, for other processes
to use, but using that to communicate with other "instances" within the
same process is unnecessary.
D-Bus doesn't distinguish between in-process and out-of-process, and
this is why making in-process calls via D-Bus is inefficient.
Suppose your objects are document windows (class DocumentWindow, a
subclass of dbus.service.Object), and they have a method
EnterText() which you want to call. Here's what happens:
* Client marshals arguments into a message
* Client sends message over UNIX socket to bus daemon
* Bus daemon sends message over UNIX socket to service
* Service (in which there is a DocumentWindow instance)
unmarshals message and runs the actual method code
* Service marshals reply (a second message)
* Service sends reply over UNIX socket to bus daemon
* Bus daemon sends reply over UNIX socket to client
* Client unmarshals reply
In the case where the client and the service are the same process,
exactly the same thing happens (although in practice you'd have to use
async calls in this situation, because of the deadlock I mentioned in a
previous mail - while the client part of the code is blocking on a
method call, the main loop isn't re-entered and the service part of the
code isn't run, unless you're using threads or something.)
However, if you know they're the same process, you can bypass D-Bus
completely: just call the EnterText() method on the DocumentWindow.
This is rather more efficient - no marshalling, no unmarshalling, no context
If dbus-python *did* distinguish between in-process and out-of-process
calls, it could provide a fast path for in-process calls which did just
call the EnterText() method directly. This seems unnecessary, since app
authors should presumably have some idea what's in their process space,
so we go for the simple approach and don't distinguish.
Also, in practice either the semantics would be subtly different, or the
call would still have higher overhead than a true local call (converting
arguments to canonical types and deep-copying lists, for instance).
The D-Bus language bindings try to make inter-process communication as
easy as an in-process method call, but if you could just be making
an in-process method call, it'll always be more efficient, and as easy
or easier, to do that instead.
More information about the dbus