summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Griebl <robert.griebl@qt.io>2021-07-22 16:03:09 +0200
committerRobert Griebl <robert.griebl@qt.io>2021-07-27 20:11:15 +0200
commitca39c6d952c6812d5fa75913432d6fc9dd4e8a81 (patch)
treee5d8c4538e385039126cb7e8132e3304807d6cc3
parenta1d562ce0b694f5f8d10fa0ab928242e5f164130 (diff)
downloadqtapplicationmanager-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.cpp28
-rw-r--r--src/manager-lib/qmlinprocessruntime.cpp6
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;