diff options
author | Michael Stahl <Michael.Stahl@cib.de> | 2019-02-22 19:19:27 +0100 |
---|---|---|
committer | Katarina Behrens <Katarina.Behrens@cib.de> | 2019-03-05 12:47:57 +0100 |
commit | 265caa4381c048c346c907b017561ab0fe0367ff (patch) | |
tree | 826ea80cad1783f2cf1f4af1c2fb4af15efe237b /vcl/unx/kde5 | |
parent | c3751ed3c98e8ed40100a8073b97c83d9ded0803 (diff) |
tdf#119856 vcl: Qt5/KDE5 RunInMainThread
The problem with the current approach of transferring calls to the main
thread with Q_EMIT signals is that if the code that should run in the
main thread needs SolarMutex, then the non-main-thread must use
SolarMutexReleaser - but then the main thread will run not only the call
that is needed right now, but will potentially process all pending
events, and the other thread hasn't prepared for that.
We need the inter-thread feature of Qt::BlockingQueuedConnection and the
non-queued feature of Qt::DirectConnection, but this combination doesn't
appear to exist.
So the SolarMutexReleaser needs to go - but then the main thread does
need SolarMutex for some things, and hence we need to trick it into
believing it has SolarMutex with the m_bNoYieldLock hack.
Then it becomes apparent that the main thread may be blocked on either
Qt events, which is fine, or on the SalYieldMutex's m_aMutex, which will
never be released now.
So the main thread must never block on m_aMutex; the alternative is to
use the same approach as the osx code (and, in a somewhat different
form, the svp code), and add some condition variables on which the main
thread can block if it fails to acquire the m_aMutex immediately.
It's even possible to do this in a somewhat generic way with lambdas.
This does appear to work, but it makes the Q_EMIT approach entirely
untenable, because now the main thread will be blocked on the condition
variable and the non-main-thread will be blocked until the Qt event is
processed.
Change-Id: I6480a6b909d5ec8814b2ff10dbefb0f3686a83c7
Reviewed-on: https://gerrit.libreoffice.org/68232
Tested-by: Jenkins
Reviewed-by: Katarina Behrens <Katarina.Behrens@cib.de>
Diffstat (limited to 'vcl/unx/kde5')
-rw-r--r-- | vcl/unx/kde5/KDE5SalInstance.cxx | 23 | ||||
-rw-r--r-- | vcl/unx/kde5/KDE5SalInstance.hxx | 8 |
2 files changed, 12 insertions, 19 deletions
diff --git a/vcl/unx/kde5/KDE5SalInstance.cxx b/vcl/unx/kde5/KDE5SalInstance.cxx index 6c5bc9341705..6350d10c2187 100644 --- a/vcl/unx/kde5/KDE5SalInstance.cxx +++ b/vcl/unx/kde5/KDE5SalInstance.cxx @@ -44,21 +44,16 @@ KDE5SalInstance::KDE5SalInstance() pSVData->maAppData.mxToolkitName = OUString("kde5"); KDE5SalData::initNWF(); - - connect(this, &KDE5SalInstance::createFrameSignal, this, &KDE5SalInstance::CreateFrame, - Qt::BlockingQueuedConnection); - connect(this, &KDE5SalInstance::createFilePickerSignal, this, - &KDE5SalInstance::createFilePicker, Qt::BlockingQueuedConnection); } SalFrame* KDE5SalInstance::CreateFrame(SalFrame* pParent, SalFrameStyleFlags nState) { - if (!IsMainThread()) - { - SolarMutexReleaser aReleaser; - return Q_EMIT createFrameSignal(pParent, nState); - } - return new KDE5SalFrame(static_cast<KDE5SalFrame*>(pParent), nState, true); + SalFrame* pRet(nullptr); + RunInMainThread(std::function([&pRet, pParent, nState]() { + pRet = new KDE5SalFrame(static_cast<KDE5SalFrame*>(pParent), nState, true); + })); + assert(pRet); + return pRet; } uno::Reference<ui::dialogs::XFilePicker2> @@ -66,7 +61,11 @@ KDE5SalInstance::createFilePicker(const uno::Reference<uno::XComponentContext>& { if (!IsMainThread()) { - return Q_EMIT createFilePickerSignal(xMSF); + uno::Reference<ui::dialogs::XFilePicker2> xRet; + RunInMainThread( + std::function([&xRet, this, xMSF]() { xRet = this->createFilePicker(xMSF); })); + assert(xRet); + return xRet; } // In order to insert custom controls, KDE5FilePicker currently relies on KFileWidget diff --git a/vcl/unx/kde5/KDE5SalInstance.hxx b/vcl/unx/kde5/KDE5SalInstance.hxx index 3cca255f9b2c..5980ea4699cc 100644 --- a/vcl/unx/kde5/KDE5SalInstance.hxx +++ b/vcl/unx/kde5/KDE5SalInstance.hxx @@ -42,13 +42,7 @@ public: virtual bool IsMainThread() const override; -Q_SIGNALS: - SalFrame* createFrameSignal(SalFrame* pParent, SalFrameStyleFlags nStyle); - - css::uno::Reference<css::ui::dialogs::XFilePicker2> - createFilePickerSignal(const css::uno::Reference<css::uno::XComponentContext>&); - -private Q_SLOTS: +private: virtual SalFrame* CreateFrame(SalFrame* pParent, SalFrameStyleFlags nStyle) override; virtual css::uno::Reference<css::ui::dialogs::XFilePicker2> |