Race condition with dbus_connection_send_with_reply()?

Schmottlach, Glenn glenn.schmottlach at harman.com
Tue Mar 3 12:35:36 PST 2009


I hope someone can shed some light on the "correct" way to issue an
asynchronous request using dbus_connection_send_with_reply().

I have a client application (using the C++ binding - not glib) that has
two threads. The "main" thread basically only runs the
dispatch/main-loop of D-Bus. A separate worker thread uses a private
connection to issue asynchronous requests. The responses are dispatched
from the "main" main-loop thread.

What I "want" to happen is to be notified when a pending request is
complete (or timed out) and have that callback function called. From
within the notification callback the code should be able to access data
stored in a pending call slot.

In pseudo-code I would expect the worker thread to do something like
this (if I were using the raw D-Bus library).

int slotdata=5;
dbus_int32_t dataslot = -1;

// Allocate a pending call slot
dbus_pending_call_allocate_data_slot(&dataslot);

DBusPendingCall *pending;

Step 1)
dbus_connection_send_with_reply(conn, msg, &pending, timeout);

Step 2)
dbus_pending_call_set_notify(pending, notifyCallback, 0, NULL);

Step 3)
dbus_pending_call_set_data(pending, dataslot, &slotdata, NULL);

Here's the problem as I see it. The only way to get a DBusPendingCall
object is to call dbus_connection_send_with_reply(). Until I get that
object I cannot set a notification callback or initialize my slot with
data. Let's assume I'm on a speedy machine (or the main thread runs at a
higher priority than the "worker" thread). It's entirely possible that
the request has been made (Step 1) and the main thread has dispatched
the request and received the response BEFORE the worker thread has
executed Steps 2 or 3. This means my notification callback could not
have been called (on the main-loop thread) or the slot may remain
uninitialized. I have seen this behavior in my non-debug code
(apparently the main-loop thread in the debugged version is just slow
enough).

So, it's a bit of a chicken-and-the-egg problem. I need a
DBusPendingCall object in order to set the notification callback and
initialize the dataslot BEFORE I want to issue the request. What is the
correct way to handle this using the D-Bus library? Is there another way
to create an "empty" DBusPendingCall without sending the request? It
seems there might be hole here that would preclude the use of using
multiple threads with the library.

Thanks . . .



 

 



 

 

39001 West 12 Mile Road

Farmington Hills, MI 48331, U.S.A.

Phone: +1 248 592 3217

Fax: +1 248 994 2703

Email: Glenn.Schmottlach at harman.com

Web: www.harman.com

 

GLENN SCHMOTTLACH

Principal Software Engineer

Harman/Becker Automotive Systems

 

 

 

			

Confidentiality Notice: This e-mail message, including any attachments,
is for the sole use of the intended recipient(s) and may contain
confidential and privileged information. Any unauthorized review, use,
disclosure or distribution is prohibited. If you are not the intended
recipient, please contact the sender by return e-mail and destroy all
copies of the original message.

 




More information about the dbus mailing list