Signal delivery between two applications delayed
I'm working to connect two programs using D-Bus. The first program is my own, written in C# and using dbus-sharp. The second is written by a 3rd-party in C++ using Qt and QtDBus. The second program exposes an object with two methods and two signals (this is what I'm trying to plug in to). In my program I've written the D-Bus interface, and I've been able to get the proxy object and call its methods. I have received signals, but in an odd manner. I do not receive the signals asynchronously; I only receive signals after calling one of the proxy object's methods.
To check my sanity, I duplicated the issue using completely unrelated code. For this test, I used the QtDBus example project "remotecontrolledcar". The subproject, "car", creates a simple scene for driving a remote-controlled car using D-Bus. The exported Car object defines a signal, but never emits it. In order to create a useful test, I have Car::timerEvent(QTimerEvent*) emit crashed() when the car reaches a certain height (i.e. transform().dy() < -200). For the client program, I simply reimplemented Qt's "controller" subproject using C#, dbus-sharp, and (yuck!) winforms. I subscribe to the crashed event with a simple handler that shows a MessageBox with the message "CRASHED!".
With my C# controller, I can drive the car just fine. Using dbus-monitor, I can also observe that the signal is sent:
signal sender=:1.232 -> dest=(null destination) serial=9 path=/Car; interface=com.trolltech.Examples.CarInterface; member=crashed
Although I see this signal get sent, nothing occurs on the client. Only after I click any of the method buttons do I get the signal.
I guess my question is, what gives?
Test Operating System: Ubuntu 10.04 LTS dbus-sharp version: 2.0.0.0 (from 1863311ffdb216b15541b920fef565159b60dec4, compiled using VS on Win7) libQtDBus version: 4.6.2
Hi, I'm also affected by this issue. Looking at the source code your assertion is correct, messages are delayed until the next method invocation you make via DBus#.
I noticed you'd forked the repository, did you make any progress on correcting delivery?
Ok, I've done some digging. Looks like this is by design. If you're using dbus-sharp-glib you can call:
BusG.init (bus)
Which will post a job to the GLib main loop running the Iterate method on the Connection object, causing signal delivery. Otherwise you could call Iterate in a while loop from somewhere in your program.
HTH
Understood.
I arrived at the while(true) Bus.Iterate() option too. Constantly calling Iterate on a separate thread seems like a nasty solution, especially when other D-Bus solutions will deliver signals asynchronously. Perhaps they also have a delivery thread running under the hood? Do you know if D-Bus endpoints are intended to poll for signals, or are signals supposed to be pushed to them automatically?
Well, the way I understand it, the bus is just a message exchange across a byte stream. So, for signals to work something has to be blocked waiting for the next one to arrive, I.e. a thread as you've been doing or a job in an event loop.