From 399d77a38ff52d33dc871a5b221db253308b7436 Mon Sep 17 00:00:00 2001 From: Peter Varga Date: Fri, 28 Jul 2017 13:31:06 +0200 Subject: Destruct BrowserContextAdapter together with WebEngineContext in widget BrowserContext needs IO thread to be destructed properly. Without WebEngineContext dependency it would be destructed together with the corresponding QWebEngineProfile which can outlive the WebEngineContext. Task-number: QTBUG-62147 Change-Id: Ia34215f379c6c803499848bf009e25a64b5cdb98 Reviewed-by: Allan Sandfeld Jensen --- src/webenginewidgets/api/qwebengineprofile.cpp | 32 +++++++++++++++++++------- src/webenginewidgets/api/qwebengineprofile_p.h | 19 +++++++++++++-- 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp index a4810d272..f120ae51e 100644 --- a/src/webenginewidgets/api/qwebengineprofile.cpp +++ b/src/webenginewidgets/api/qwebengineprofile.cpp @@ -145,24 +145,35 @@ using QtWebEngineCore::BrowserContextAdapter; \sa QWebEngineDownloadItem */ -QWebEngineProfilePrivate::QWebEngineProfilePrivate(QSharedPointer browserContext) +QWebEngineBrowserContext::QWebEngineBrowserContext(QSharedPointer browserContext, QWebEngineProfilePrivate *profile) + : QObject(BrowserContextAdapter::globalQObjectRoot()) + , browserContextRef(browserContext) + , m_profile(profile) +{ + browserContextRef->addClient(m_profile); +} + +QWebEngineBrowserContext::~QWebEngineBrowserContext() +{ + Q_ASSERT(m_profile); + // In the case the user sets this profile as the parent of the interceptor + // it can be deleted before the browser-context still referencing it is. + browserContextRef->setRequestInterceptor(nullptr); + browserContextRef->removeClient(m_profile); +} + +QWebEngineProfilePrivate::QWebEngineProfilePrivate(QSharedPointer browserContext) : m_settings(new QWebEngineSettings()) , m_scriptCollection(new QWebEngineScriptCollection(new QWebEngineScriptCollectionPrivate(browserContext->userResourceController()))) - , m_browserContextRef(browserContext) + , m_browserContext(new QWebEngineBrowserContext(browserContext, this)) { - m_browserContextRef->addClient(this); m_settings->d_ptr->initDefaults(browserContext->isOffTheRecord()); } QWebEngineProfilePrivate::~QWebEngineProfilePrivate() { - // In the case the user sets this profile as the parent of the interceptor - // it can be deleted before the browser-context still referencing it is. - m_browserContextRef->setRequestInterceptor(nullptr); - delete m_settings; m_settings = 0; - m_browserContextRef->removeClient(this); Q_FOREACH (QWebEngineDownloadItem* download, m_ongoingDownloads) { if (download) @@ -172,6 +183,11 @@ QWebEngineProfilePrivate::~QWebEngineProfilePrivate() m_ongoingDownloads.clear(); } +QSharedPointer QWebEngineProfilePrivate::browserContext() const +{ + return m_browserContext->browserContextRef; +} + void QWebEngineProfilePrivate::cancelDownload(quint32 downloadId) { browserContext()->cancelDownload(downloadId); diff --git a/src/webenginewidgets/api/qwebengineprofile_p.h b/src/webenginewidgets/api/qwebengineprofile_p.h index 4d31c5a81..067a5bd7e 100644 --- a/src/webenginewidgets/api/qwebengineprofile_p.h +++ b/src/webenginewidgets/api/qwebengineprofile_p.h @@ -65,15 +65,30 @@ class BrowserContextAdapter; QT_BEGIN_NAMESPACE +class QWebEngineProfilePrivate; class QWebEngineSettings; +// This is a wrapper class for BrowserContextAdapter. BrowserContextAdapter must be destructed before WebEngineContext +// is destructed. Therefore access it via the QWebEngineBrowserContext which parent is the WebEngineContext::globalQObject. +// This guarantees the destruction together with the WebEngineContext. +class QWebEngineBrowserContext : public QObject { +public: + QWebEngineBrowserContext(QSharedPointer browserContext, QWebEngineProfilePrivate *profile); + ~QWebEngineBrowserContext(); + + QSharedPointer browserContextRef; + +private: + QWebEngineProfilePrivate *m_profile; +}; + class QWebEngineProfilePrivate : public QtWebEngineCore::BrowserContextAdapterClient { public: Q_DECLARE_PUBLIC(QWebEngineProfile) QWebEngineProfilePrivate(QSharedPointer browserContext); ~QWebEngineProfilePrivate(); - QSharedPointer browserContext() const { return m_browserContextRef; } + QSharedPointer browserContext() const; QWebEngineSettings *settings() const { return m_settings; } void cancelDownload(quint32 downloadId); @@ -86,7 +101,7 @@ private: QWebEngineProfile *q_ptr; QWebEngineSettings *m_settings; QScopedPointer m_scriptCollection; - QSharedPointer m_browserContextRef; + QPointer m_browserContext; QMap > m_ongoingDownloads; }; -- cgit v1.2.3