[Fwd: Re: [Dbus-cxx-devel] Some 'sent' messages don't get sent]

Patrick Allison patrick at phys.hawaii.edu
Fri Sep 4 11:54:42 PDT 2009


> On Tue, Sep 1, 2009 at 12:20 PM, Rick L. Vinyard,
> Jr.<rvinyard at cs.nmsu.edu> wrote:
> >
> > Sorry for the flurry of messages (OK, two is not a flurry), but I did a
> > bit more debugging staring around at code. I think the problem's a race
> > condition between the watch thread and the dispatch thread (and I really
> > hope this isn't just some bug in my version of D-Bus, but I didn't see
> > anything like it in the bugzilla for D-Bus).
> 
> The general "threads bug" is:
> https://bugs.freedesktop.org/show_bug.cgi?id=857

Hi Colin:

I saw that bug, but all the activity on it seemed to be in reference to
dbus_connection_send_with_reply_and_block(), and this problem shows up
just with dbus_connection_send.

I'm also not positive this is just a threading bug: I think it could occur
in a single-threaded program, but only if DBusWakeupMainFunction called
dbus_connection_dispatch(): then when dbus_watch_handle() is called on the read
watch, _dbus_connection_queue_received_message_link calls DBusWakeupMainFunction,
which calls dbus_connection_dispatch, which calls the message handler, which
calls dbus_connection_send which fails because the I/O path is still held by
dbus_watch_handle(), leaving a message queued in the outgoing path but no 
write watch set. Note that I'm not positive that this can happen, so if this
is dumb/impossible, please feel free to correct me. It is happening in
the threaded version, but I don't see anything which would prevent it in a
non-threaded version (I'm not familiar enough right now with the low-level API
to write a test case to see if this could happen).

I did open a bug specifically for this issue at:

https://bugs.freedesktop.org/show_bug.cgi?id=23584

It seems like the bugfix would be to have 
_dbus_connection_send_preallocated_unlocked_no_update()
somehow install the write watch if there are messages remaining to send. It
currently just wakes up the mainloop, but without an enabled write watch,
I don't see why the mainloop would have anything to do - it would just
check the dispatch status, which would be complete, and promptly wait on
the read watch descriptor since the write watch descriptor isn't enabled.

To do this, though, I think there would have to be a helper function from
the transport to check/install the write watch (basically expose the functionality
of dbus-transport-socket.c's check_write_watch), and I'm not sure how best
to do that.

Patrick



More information about the dbus mailing list