diff options
author | Robert Griebl <robert.griebl@qt.io> | 2021-07-22 16:03:09 +0200 |
---|---|---|
committer | Robert Griebl <robert.griebl@qt.io> | 2021-07-27 20:11:15 +0200 |
commit | ca39c6d952c6812d5fa75913432d6fc9dd4e8a81 (patch) | |
tree | e5d8c4538e385039126cb7e8132e3304807d6cc3 | |
parent | a1d562ce0b694f5f8d10fa0ab928242e5f164130 (diff) | |
download | qtapplicationmanager-ca39c6d952c6812d5fa75913432d6fc9dd4e8a81.tar.gz |
Avoid race condition on Intent creation during app startup
Change-Id: I159db37d55dea3a85a52117013b24611cbbb8ac4
Reviewed-by: Dominik Holland <dominik.holland@qt.io>
-rw-r--r-- | src/manager-lib/intentaminterface.cpp | 28 | ||||
-rw-r--r-- | src/manager-lib/qmlinprocessruntime.cpp | 6 |
2 files changed, 18 insertions, 16 deletions
diff --git a/src/manager-lib/intentaminterface.cpp b/src/manager-lib/intentaminterface.cpp index 841a3a6d..7932d3e5 100644 --- a/src/manager-lib/intentaminterface.cpp +++ b/src/manager-lib/intentaminterface.cpp @@ -227,7 +227,7 @@ bool IntentServerAMImplementation::checkApplicationCapabilities(const QString &a return false; auto capabilities = app->capabilities(); - for (auto cap : requiredCapabilities) { + for (const auto &cap : requiredCapabilities) { if (!capabilities.contains(cap)) return false; } @@ -296,14 +296,18 @@ void IntentClientAMImplementation::initialize(IntentClient *intentClient) Q_DECL void IntentClientAMImplementation::requestToSystem(QPointer<IntentClientRequest> icr) { - IntentServerRequest *isr = m_issi->requestToSystem(icr->requestingApplicationId(), icr->intentId(), - icr->applicationId(), icr->parameters()); + // we need to delay the request by one event loop iteration to (a) avoid a race condition + // on app startup and (b) have consistent behavior in single- and multi-process mode - QUuid requestId = isr ? isr->requestId() : QUuid(); + QMetaObject::invokeMethod(m_ic, [icr, this]() { + IntentServerRequest *isr = m_issi->requestToSystem(icr->requestingApplicationId(), icr->intentId(), + icr->applicationId(), icr->parameters()); + QUuid requestId = isr ? isr->requestId() : QUuid(); - QMetaObject::invokeMethod(m_ic, [icr, requestId, this]() { - emit requestToSystemFinished(icr.data(), requestId, requestId.isNull(), - requestId.isNull() ? qL1S("No matching intent handler registered.") : QString()); + QMetaObject::invokeMethod(m_ic, [icr, requestId, this]() { + emit requestToSystemFinished(icr.data(), requestId, requestId.isNull(), + requestId.isNull() ? qL1S("No matching intent handler registered.") : QString()); + }, Qt::QueuedConnection); }, Qt::QueuedConnection); } @@ -392,13 +396,11 @@ IntentServerInProcessIpcConnection *IntentServerInProcessIpcConnection::create(A IntentServerAMImplementation *iface) { auto ipcConnection = new IntentServerInProcessIpcConnection(application, iface); - if (application) { - QMetaObject::invokeMethod(ipcConnection, - [ipcConnection, application]() { ipcConnection->setReady(application); }, - Qt::QueuedConnection); - } else { + if (application) + ipcConnection->setReady(application); + else ipcConnection->m_ready = true; - } + s_ipcConnections << ipcConnection; return ipcConnection; } diff --git a/src/manager-lib/qmlinprocessruntime.cpp b/src/manager-lib/qmlinprocessruntime.cpp index d94f8954..9777d257 100644 --- a/src/manager-lib/qmlinprocessruntime.cpp +++ b/src/manager-lib/qmlinprocessruntime.cpp @@ -78,8 +78,6 @@ bool QmlInProcessRuntime::start() { Q_ASSERT(!m_rootObject); - setState(Am::StartingUp); - if (!m_inProcessQmlEngine) return false; @@ -127,6 +125,8 @@ bool QmlInProcessRuntime::start() emit signaler()->aboutToStart(this); + setState(Am::StartingUp); + // We are running each application in it's own, separate Qml context. // This way, we can export an unique ApplicationInterface object for each app QQmlContext *appContext = new QQmlContext(m_inProcessQmlEngine->rootContext(), this); @@ -161,10 +161,10 @@ bool QmlInProcessRuntime::start() } } m_rootObject = obj; + setState(Am::Running); if (!m_document.isEmpty()) openDocument(m_document, QString()); - setState(Am::Running); } }, Qt::QueuedConnection); return true; |