diff options
author | Robert Griebl <robert.griebl@qt.io> | 2021-07-22 16:03:09 +0200 |
---|---|---|
committer | Robert Griebl <robert.griebl@qt.io> | 2022-08-05 15:50:30 +0200 |
commit | 7c906b2e4a22721e7c7bae99009c38a42617fdeb (patch) | |
tree | 31d484d93185f826a52ab93d82e0d3425044d54b | |
parent | 98030a28b9ac4a6f4b8b2d10b2c2a26c348cafc1 (diff) | |
download | qtapplicationmanager-7c906b2e4a22721e7c7bae99009c38a42617fdeb.tar.gz |
Avoid race condition on Intent creation during app startup
Change-Id: I159db37d55dea3a85a52117013b24611cbbb8ac4
Reviewed-by: Dominik Holland <dominik.holland@qt.io>
(cherry picked from commit ca39c6d952c6812d5fa75913432d6fc9dd4e8a81)
Reviewed-by: Bernd Weimer <bernd.weimer@qt.io>
-rw-r--r-- | src/manager-lib/intentaminterface.cpp | 28 | ||||
-rw-r--r-- | src/manager-lib/qmlinprocessruntime.cpp | 6 |
2 files changed, 19 insertions, 15 deletions
diff --git a/src/manager-lib/intentaminterface.cpp b/src/manager-lib/intentaminterface.cpp index 049c4266..1b8f447c 100644 --- a/src/manager-lib/intentaminterface.cpp +++ b/src/manager-lib/intentaminterface.cpp @@ -240,7 +240,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; } @@ -309,14 +309,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); } @@ -405,13 +409,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 ef08f2ea..2b2c8626 100644 --- a/src/manager-lib/qmlinprocessruntime.cpp +++ b/src/manager-lib/qmlinprocessruntime.cpp @@ -95,7 +95,6 @@ bool QmlInProcessRuntime::start() #if !defined(AM_HEADLESS) Q_ASSERT(!m_rootObject); #endif - setState(Am::StartingUp); if (!m_inProcessQmlEngine) return false; @@ -144,6 +143,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); @@ -179,9 +180,10 @@ bool QmlInProcessRuntime::start() } m_rootObject = obj; #endif + setState(Am::Running); + if (!m_document.isEmpty()) openDocument(m_document, QString()); - setState(Am::Running); } }, Qt::QueuedConnection); return true; |