Proper use of dbus_connection_send_with_reply & DBusPendingCall

Havoc Pennington hp at redhat.com
Sat Dec 29 05:55:02 PST 2007


Hi,

David Belser wrote:
> I'm working with the C++ bindings and trying to get Async method calls
> working. Here I've been digging in the archives but I'm still not sure
> of the proper use of dbus_connection_send_with_reply and
> DBusPendingCalls. One of the messages from Havoc said they shouldn't
> be used with threads.

I don't remember all the history here. There was a bug / API bug you 
mention about the race between getting the reply and setting the notify. 
We never got a patch for that I don't think, so it's still there afaik.
But I don't really remember. If you point me to the thread you mean I 
can try to figure out what I was saying then.

In general when using multiple threads, you want to be sure you only 
dispatch in a single thread, or it will be undefined which dispatching 
thread gets which messages / notifies. So, maybe that is another thing I 
said in an older thread.

Blocking on a pending call in another thread, though, is supposed to 
work afaik. (but, see my comment in "Re: [python-dbus/PyQt] Message 
loops in separate threads" from 12/18)

> As I understand it, in a multi-thread setup there are two (at least) issues:
> 
> 1 - I will be handling the reply in a different thread than the one
> that made the call, this may or may not be that big of an issue
> depending on how and what my app is doing.
> 
> 2 - There is a brief window where the dispatch thread may receive the
> reply before I've set the callback notify function.

Correct.

> The other thing that I'm confused about is the
> dbus_pending_call_allocate_data_slot &
> dbus_pending_call_free_data_slot. The language in the api doc is
> confusing -

Each pending call has an array of data slots. When you allocate a data 
slot, you're adding a slot to *all* pending call objects, not just one.

The intended usage is something like:

  int the_slot = -1; // global variable

  // when slot is needed, ensure it exists
  allocate_data_slot(&the_slot)

  // when slot is no longer needed, decrement its refcount
  free_data_slot(&the_slot)

If you allocate a slot that isn't -1, it just ups the refcount on it. So 
this makes it OK to allocate the slot in constructor and free it in the 
destructor, since the slot will exist as long as an object is using it.

The point about how the slot is global, is that you're allocating say 
"the C++ proxy slot for all pending call objects," the idea is that each 
pending call will have a C++ proxy. The data slot thing is not intended 
for callback data used in only one situation, or something like that. 
It's intended for language binding proxies basically and that's it.

Havoc



More information about the dbus mailing list