summaryrefslogtreecommitdiff
path: root/vcl/unx/kde5
diff options
context:
space:
mode:
authorMichael Stahl <Michael.Stahl@cib.de>2019-02-22 19:19:27 +0100
committerKatarina Behrens <Katarina.Behrens@cib.de>2019-03-05 12:47:57 +0100
commit265caa4381c048c346c907b017561ab0fe0367ff (patch)
tree826ea80cad1783f2cf1f4af1c2fb4af15efe237b /vcl/unx/kde5
parentc3751ed3c98e8ed40100a8073b97c83d9ded0803 (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.cxx23
-rw-r--r--vcl/unx/kde5/KDE5SalInstance.hxx8
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>