summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBartlomiej Moskal <bartlomiej.moskal@qt.io>2023-02-24 08:34:37 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-03-03 14:26:38 +0000
commit9a8f29832c047ee83cac26ab40569e35a537981b (patch)
tree7ce1f73de69d340ad20caf058152f1eb2f7636f0
parent3edc28dc5ddcd0d8aa7e9d14527035df8b4f0af2 (diff)
Android: Fix for possible thread deadlock6.4
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 Change-Id: I71aaea9ceb7c41b818ed533ce41c70b5c0e8d7de Reviewed-by: Michal Klocek <michal.klocek@qt.io> (cherry picked from commit 26c2569b73d884e3130705c77b8f2920f5645029) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-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 f2c33aa..a2044b2 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
static const char qtAndroidWebViewControllerClass[] = "org/qtproject/qt/android/view/QtAndroidWebViewController";
@@ -45,10 +48,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;");