Re: Skype and DBus: should my client library act as a server?

Thomas Downing <[email protected]>
Newsgroups gmane.comp.freedesktop.dbus
Organization Bomgar
Message-ID <[email protected]>
On Sunday, March 22, 2015 08:07:17 Lars Hanisch wrote:
> Am 18.03.2015 um 22:05 schrieb Julien JPK:
> > On 18/03/15 20:33, Simon McVittie wrote:
> >> On 18/03/15 20:00, Julien JPK wrote:
> >>>  - Start sending my requests from another thread.
> >> 
> >> Threads! You had a problem, you solved it with threads, and now you have
> >> two problems working in parallel :-)
> >> 
[snip]
> 
>  I wrote a plugin for the vdr (http://tvdr.de/) to add a DBus interface to
> it (https://github.com/flensrocker/vdr-plugin-dbus2vdr). I also started
> with libdbus, because I thought, like every other lib<core-component>,
> that should be the lib to use. It kind of worked, but had a lot of flaws
> in that multi-threaded environment, my plugin runs.
> 
>  Finally I switched to GDBus and never regret it.
> 
>  My advice: if you want to dig into DBus itself, write a new
> implementation, that fits your needs. But if you just want to use DBus,
> use an implementation the "DBus gurus" point you to. GDBus is way more
> easier to use than libdbus.
> 
> Lars.

For anybody who _really_ wants to, or must, use libdbus in a multi-threaded 
environment:

For reasons not relevant here, I used libdbus, though I am now free to explore 
replacing it with GDBus.  So I wrote a partial libdbus wrapper for our 
multitreaded app to use.  Partial, because I did not create a generic message 
content wrapper, such as proxy code generators etc.

I did integrate libdbus into an extant main epoll loop using the DBusTimeout 
and DBusWatch functions.

What I found was the key: dbus_connection_dispatch.  While this method is on 
the call stack of _any_ thread, certain other libdbus methods are not safe.

The approach I took was to call dbus_connection_send and 
dbus_connection_dispatch from the same dedicated thread.  This thread wakes up 
to do work on any Watch, Timeout, Wakeup callback, when a timeout or watch 
needs service, or when there is a queued message to send.

Arbitrary threads in our app, when sending a message is really just queueing 
that message for later send by the dedicated thread.  Messages received as the 
result of dbus_connection_dispatch are queued for later delivery by a thread 
other than the dedicated thread.

Once this is done, the only other functions that I needed to protect were the 
dbus_message_new* calls.  I wrapped these such that a mutex (or other 
protection) ensure that they block while the dedicated thread is in 
dbus_connection_dispatch.  Note that this implies the correct use of 
dbus_message_ref/unref

Parsing a message, or building a message can be done by an arbitrary thread 
without protection.

To date, all testing using the valgrind suite, -fsanitize and other tools have 
revealed no problems.  The end result is that from the perspective of an 
arbitrary thread using the wrapper, non-blocking messaging, including in-
context delivery of asynchrounous signals, method calls, and method returns 
are all available.

Your mileage may vary, as I don't use all the functions provided by libdbus; 
meaning that there may be other functions unsafe while a thread is in 
dbus_connection_dispatch.

Thomas Downing
_______________________________________________
dbus mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dbus
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.