On Thu, Feb 16, 2012 at 4:19 PM, Patrick Ohly <patrick.ohly(a)intel.com> wrote:
On Thu, 2012-02-16 at 15:32 +0100, Chris Kühl wrote:
> > One thing which
> > caught my attention is how blocking D-Bus calls are used in
> > syncevo-dbus-server.
> >
> > For example, ConnectionResource::process(): it passes the incoming data
> > on to the helper process with a blocking call. Isn't that a big no-no?
> >
>
> Yes, in this instance the client is expecting the the Reply signal so
> we can definitely do without this blocking call. This is actually how
> I wish the entire DBus interface worked; make a request and wait for a
> signal that delivers the requested data.
But that's already how D-Bus works: send a method call method, get a
reply message back. There's no need to define the D-Bus interface as
"method call without a reply + signal".
> > If the helper is busy, won't that D-Bus call completely block all
> > processing of any other events in the server for considerable periods of
> > time? Worse, if syncevo-dbus-server is blocked in a call to the helper
> > and the helper needs something from syncevo-dbus-server (like a
> > password), then we have a deadlock.
>
> True, this a problem and would require breaking the DBus interface to
> work. The only way I know how to get around this is the make the
> public DBus interface asynchronous.
No, just make the implementation of the D-Bus interface asynchronous.
The C++ bindings support that:
* Asynchronous methods are possible by declaring one parameter as a
* Result pointer and later calling the virtual function provided by
* it. Parameter passing of results is less flexible than that of
* method parameters: the later allows both std::string as well as
* const std::string &, for results only the const reference is
* supported. The Result instance is passed as pointer and then owned
* by the called method.
Have a look at Result1 in src/gdbusxx/test/example.cpp.
Ah, that's what I needed. I didn't recall that this was possible
without modifying the DBus wrapper considerably. Looks similar to the
GDbusMethodInvocation functionality.
The flow of messages then becomes:
1. syncevo-dbus-server receives method call, stores Result pointer
2. syncevo-dbus-server sends method call to helper
3. helper receives method call, replies (asynchronously or
synchronously)
4. syncevo-dbus-server receives reply
5. syncevo-dbus-server relays reply to original caller
I'll see whether I can cook up a patch.
No need. I'm now looking at how you use it in LocalTransportAgent.cpp.
That should be enough to get started implementing this.
Cheers,
Chris