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 15:26:39 +0000
commit76a9b10dcea470d0b2a11c6c92194433e8c4a7ca (patch)
treee5f2ae21a8cccdc71a229fac43c3d9991803e10a
parentec149ad5fc57d72db383d7a8cef1f89bce564efb (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 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 0358ae0..813aa01 100644
--- a/src/plugins/android/qandroidwebview.cpp
+++ b/src/plugins/android/qandroidwebview.cpp
@@ -51,6 +51,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";
@@ -81,10 +84,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;");