summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBartlomiej Moskal <bartlomiej.moskal@qt.io>2023-02-24 08:34:37 +0100
committerBartlomiej Moskal <bartlomiej.moskal@qt.io>2023-03-03 09:31:53 +0000
commit26c2569b73d884e3130705c77b8f2920f5645029 (patch)
tree1aafd32079dab5d471ca23a0461ec271ab103096
parent91a14c6af43f2282d4378ff17fcd9f41ca539ac0 (diff)
Android: Fix for possible thread deadlock
QtAndroidWebViewController constructor blocks a qGuiThread until the WebView is created and configured in UI thread. Such an implementation can easily lead to the deadlock (For example in the case of handling InputConnection - it is exactly the opposite. UI thread is blocked and waits for handling event by qGuiThread). That's why we need to lock AndroidDeadlockProtector before blocking qGuiThread. This implementation resolves potential deadlock using AndroidDeadlockProtector. If protector cannot by locked, qGuiThread will handle events to make it possible. Fixes: QTBUG-82810 Pick-to: 6.5 6.4 6.2 5.15 Change-Id: I71aaea9ceb7c41b818ed533ce41c70b5c0e8d7de Reviewed-by: Michal Klocek <michal.klocek@qt.io>
-rw-r--r--src/plugins/android/qandroidwebview.cpp15
1 files changed, 15 insertions, 0 deletions
diff --git a/src/plugins/android/qandroidwebview.cpp b/src/plugins/android/qandroidwebview.cpp
index 5e13c08..57f0864 100644
--- a/src/plugins/android/qandroidwebview.cpp
+++ b/src/plugins/android/qandroidwebview.cpp
@@ -15,6 +15,9 @@
#include <QtCore/qurl.h>
#include <QtCore/qdebug.h>
+#include <QAbstractEventDispatcher>
+#include <QThread>
+
QT_BEGIN_NAMESPACE
QAndroidWebViewSettingsPrivate::QAndroidWebViewSettingsPrivate(QJniObject viewController, QObject *p)
@@ -92,10 +95,22 @@ QAndroidWebViewPrivate::QAndroidWebViewPrivate(QObject *p)
, m_callbackId(0)
, m_window(0)
{
+ // QtAndroidWebViewController constructor blocks a qGuiThread until
+ // the WebView is created and configured in UI thread.
+ // That is why we cannot proceed until AndroidDeadlockProtector is locked
+ while (!QtAndroidPrivate::acquireAndroidDeadlockProtector()) {
+ auto eventDispatcher = QThread::currentThread()->eventDispatcher();
+ if (eventDispatcher)
+ eventDispatcher->processEvents(
+ QEventLoop::ExcludeUserInputEvents|QEventLoop::ExcludeSocketNotifiers);
+ }
m_viewController = QJniObject(qtAndroidWebViewControllerClass,
"(Landroid/app/Activity;J)V",
QtAndroidPrivate::activity(),
m_id);
+
+ QtAndroidPrivate::releaseAndroidDeadlockProtector();
+
m_webView = m_viewController.callObjectMethod("getWebView",
"()Landroid/webkit/WebView;");
m_settings = new QAndroidWebViewSettingsPrivate(m_viewController, this);