Make QDBusConnectionPrivate::getNameOwnerNoCache work in our thread

In two commits, we will attempt to call this function from the manager
thread, so we need to be sure this function works from there. Right now,
it would deadlock in QDBusPendingCallPrivate::waitForFinished(), inside
QDBusConnectionPrivate::sendWithReply().

The solution is simple: expand sendWithReply to the sendWithReplyAsync
function it calls anyway, but tell the internal DBusPendingCall to
finish before we call waitForFinished().

Change-Id: Iee8cbc07c4434ce9b560ffff13d0749013d771ab
Reviewed-by: Albert Astals Cid <aacid@kde.org>
Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
This commit is contained in:
Thiago Macieira 2015-03-30 19:34:03 -07:00
parent d8148edb23
commit cc5ab92cd9

View File

@ -2362,9 +2362,21 @@ QString QDBusConnectionPrivate::getNameOwnerNoCache(const QString &serviceName)
QStringLiteral("GetNameOwner"));
QDBusMessagePrivate::setParametersValidated(msg, true);
msg << serviceName;
QDBusMessage reply = sendWithReply(msg, QDBus::Block);
if (reply.type() == QDBusMessage::ReplyMessage)
return reply.arguments().at(0).toString();
QDBusPendingCallPrivate *pcall = sendWithReplyAsync(msg, Q_NULLPTR, Q_NULLPTR, Q_NULLPTR);
if (thread() == QThread::currentThread()) {
// this function may be called in our own thread and
// QDBusPendingCallPrivate::waitForFinished() would deadlock there
q_dbus_pending_call_block(pcall->pending);
}
pcall->waitForFinished();
msg = pcall->replyMessage;
if (!pcall->ref.deref())
delete pcall;
if (msg.type() == QDBusMessage::ReplyMessage)
return msg.arguments().at(0).toString();
return QString();
}