diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index a6105d44038..119a354d828 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -2056,20 +2056,10 @@ QDBusMessage QDBusConnectionPrivate::sendWithReply(const QDBusMessage &message, QDBusPendingCallPrivate *pcall = sendWithReplyAsync(message, nullptr, nullptr, nullptr, timeout); Q_ASSERT(pcall); - if (pcall->replyMessage.type() == QDBusMessage::InvalidMessage) { - // need to wait for the reply - if (mode == QDBus::BlockWithGui) { - pcall->watcherHelper = new QDBusPendingCallWatcherHelper; - QEventLoop loop; - loop.connect(pcall->watcherHelper, &QDBusPendingCallWatcherHelper::reply, &loop, &QEventLoop::quit); - loop.connect(pcall->watcherHelper, &QDBusPendingCallWatcherHelper::error, &loop, &QEventLoop::quit); - - // enter the event loop and wait for a reply - loop.exec(QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents); - } else { - pcall->waitForFinished(); - } - } + if (mode == QDBus::BlockWithGui) + pcall->waitForFinishedWithGui(); + else + pcall->waitForFinished(); QDBusMessage reply = pcall->replyMessage; lastError = QDBusError(reply); // set or clear error @@ -2130,6 +2120,7 @@ QDBusPendingCallPrivate *QDBusConnectionPrivate::sendWithReplyAsync(const QDBusM pcall->setReplyCallback(receiver, returnMethod); if (errorMethod) { + Q_ASSERT(!pcall->watcherHelper); pcall->watcherHelper = new QDBusPendingCallWatcherHelper; connect(pcall->watcherHelper, SIGNAL(error(QDBusError,QDBusMessage)), receiver, errorMethod, Qt::QueuedConnection); diff --git a/src/dbus/qdbuspendingcall.cpp b/src/dbus/qdbuspendingcall.cpp index 6cbca5ea3a4..f9d414d1bda 100644 --- a/src/dbus/qdbuspendingcall.cpp +++ b/src/dbus/qdbuspendingcall.cpp @@ -206,6 +206,26 @@ void QDBusPendingCallPrivate::waitForFinished() waitForFinishedCondition.wait(&mutex); } +void QDBusPendingCallPrivate::waitForFinishedWithGui() +{ + QEventLoop loop; + + { + const auto locker = qt_scoped_lock(mutex); + if (replyMessage.type() != QDBusMessage::InvalidMessage) + return; // already finished + + Q_ASSERT(!watcherHelper); + watcherHelper = new QDBusPendingCallWatcherHelper; + loop.connect(watcherHelper, &QDBusPendingCallWatcherHelper::reply, &loop, + &QEventLoop::quit); + loop.connect(watcherHelper, &QDBusPendingCallWatcherHelper::error, &loop, + &QEventLoop::quit); + } + + loop.exec(QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents); +} + /*! Creates a copy of the \a other pending asynchronous call. Note that both objects will refer to the same pending call. diff --git a/src/dbus/qdbuspendingcall_p.h b/src/dbus/qdbuspendingcall_p.h index f19acfd0756..2795cc3ecf8 100644 --- a/src/dbus/qdbuspendingcall_p.h +++ b/src/dbus/qdbuspendingcall_p.h @@ -68,6 +68,7 @@ public: ~QDBusPendingCallPrivate(); bool setReplyCallback(QObject *target, const char *member); void waitForFinished(); + void waitForFinishedWithGui(); void setMetaTypes(int count, const QMetaType *types); void checkReceivedSignature(); };