2

I am currently trying to implement a library using QtDBus. I successfully register a service and object on dbus. But then when I use QDBusInterface, dbus seems to be blocked on Introspect message as shown by dbus-monitor traces:

method call sender=:1.363 -> dest=org.freedesktop.DBus serial=3 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=GetNameOwner
string "my.test.test"
method call sender=:1.363 -> dest=my.test.test serial=4 path=/;interface=org.freedesktop.DBus.Introspectable; member=Introspect

here is some pieces of code to explain how I manage dbus. I use it in a QThread to use its own even loop (As I implement a library, I don't want any blocking call, such exec(), in the main thread). So, I initialize it in this way:

Worker::Worker()
{
   moveToThread(_thread);
   _dbus = new DbusHandler();
   _dbus->moveToThread(_thread);

   connect(_thread, SIGNAL(started()), _dbus, SLOT(initializeDBus()));
   connect(this, SIGNAL(sig_send(const QString)), _dbus, SLOT(send(const QString)));

   _thread->start();     
}

void DBusHandler::initializeDBus()
{
   QDBusConnection _connection = QDBusConnection::sessionBus();

   if ( ! _connection.isConnected())
      throw runtime_error("Could not connect to DBUS.");

   // register the serviceName
   if ( ! _connection.registerService(serviceName) )
      throw runtime_error("Could not register the service using    QDBusConnection::registerService");

   // register the current object to the path "/"
   if ( ! _connection.registerObject("/", this, QDBusConnection::ExportAllSlots))
      throw runtime_error("Could not register object using QDBusConnection::registerObject");
}

Then I send the message on Dbus using the same thread using this slot connected to the signal sig_send() of a Worker class (which is in the same thread).

void DBusHandler::send(const QString message)
{
    QDBusInterface interface(serviceName, "/", "", QDBusConnection::sessionBus
    interface.asyncCall(serviceName, message);
}

This method allows to emit sig_send signal and send the message to the above method.

void Worker::send(const QString message)
{
    emit sig_send(message);
}

Finally my main is looked like:

int main(int , char** )
{
    Worker* worker = new Worker();
    while(true)
        worker->send("Hello world!");
}

Strangely, this code seems to work well with Qt 4.6.2 but not with Qt 4.8.4. More amazingly, it works also if I remove the infinite loop in the main and send only one message. Does anyone have a solution or an explanation to this problem?

  • http://stackoverflow.com/questions/24058519/how-to-use-qt-dbus-bindings-without-blocking-the-main-thread – boiyee Dec 04 '14 at 17:10

0 Answers0