PDA

View Full Version : QDBusInterface is blocking dbus



aerkis
27th March 2014, 13:16
Hi all,

I am currently trying to implement a process 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


It seems to be a regular problem with QtDbus as shown by following posts:
http://www.qtcentre.org/threads/36996-QDBusInterface-blocking-dbus
https://bugreports.qt-project.org/browse/QTBUG-14485

I have tried to use QDbusConnection::asyncCall() to remove DBusInterface. In this use case, the message is correctly sent on DBus but it is never received.

In conclusion, I was not able to find a correct solution to my problem, so I hope someone here can help me find a way out, thanks.

anda_skoa
30th March 2014, 12:27
You seem to have forgotten to post any code of your application.

Cheers,
_

aerkis
31st March 2014, 10:02
Sorry, here is some pieces of code :

I use Dbus 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);
_thread->start();

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

}



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

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

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

// register the current object to the path "/"
if ( not _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:


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

With this code, Dbus is blocking on QDBusInterface introspection (as explained in the previous post)
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?

Thanks in advance.