summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan-Marek Glogowski <glogow@fbihome.de>2021-11-17 10:29:24 +0100
committerJan-Marek Glogowski <glogow@fbihome.de>2022-01-21 12:42:20 +0100
commita9bb94e28a6757719a2e833c9d3ca17b3205283b (patch)
tree23e68d198a5fc609bfbb5567b0be90f2f4638935
parent3eb6d764b3023500f2299d36bf1860bc8e67db9f (diff)
VCL fix shutdown when run via system loop
Adds DoQuit and SAL_USE_SYSTEM_LOOP to complement DoExecute. Makes it easier to switch between a LO with and without nested event processing. Unfortunatly the recovery dialogs run outside of Application::Execute(), so this currently also disables recovery handling. Follow-up (and no more Emscripten-specific) change to commit 93133585b5b52e38defc3162eeb1e7704dceafcb ("WASM optionally run any app via system loop"). Change-Id: I1b622065d7fa0c5ad03a7c7daaf8241dcc3f09a3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128717 Tested-by: Jenkins Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
-rw-r--r--desktop/source/app/app.cxx1
-rw-r--r--include/vcl/svapp.hxx6
-rw-r--r--vcl/README.vars.md1
-rw-r--r--vcl/inc/qt5/QtInstance.hxx1
-rw-r--r--vcl/inc/salinst.hxx4
-rw-r--r--vcl/inc/svdata.hxx2
-rw-r--r--vcl/qt5/QtInstance.cxx19
-rw-r--r--vcl/qt5/QtTimer.cxx11
-rw-r--r--vcl/source/app/salvtables.cxx14
-rw-r--r--vcl/source/app/svapp.cxx38
-rw-r--r--vcl/source/app/svdata.cxx7
11 files changed, 77 insertions, 27 deletions
diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx
index b14c0d94299a..ada608229f8b 100644
--- a/desktop/source/app/app.cxx
+++ b/desktop/source/app/app.cxx
@@ -2020,6 +2020,7 @@ void Desktop::OpenClients()
bool bExistsSessionData = false;
bool const bDisableRecovery
= getenv("OOO_DISABLE_RECOVERY") != nullptr
+ || IsOnSystemEventLoop()
|| !officecfg::Office::Recovery::RecoveryInfo::Enabled::get();
impl_checkRecoveryState(bCrashed, bExistsRecoveryData, bExistsSessionData);
diff --git a/include/vcl/svapp.hxx b/include/vcl/svapp.hxx
index f4d065f1d664..137177bbfbb0 100644
--- a/include/vcl/svapp.hxx
+++ b/include/vcl/svapp.hxx
@@ -1323,6 +1323,12 @@ public:
*/
static void EndAllPopups();
+ /** Returns true, if the VCL plugin runs on the system event loop.
+ *
+ * AKA the VCL plugin can't handle nested event loops, like WASM or mobile.
+ */
+ static bool IsOnSystemEventLoop();
+
///@}
// For vclbootstrapprotector:
diff --git a/vcl/README.vars.md b/vcl/README.vars.md
index c7971b734be0..c83ca657ef9f 100644
--- a/vcl/README.vars.md
+++ b/vcl/README.vars.md
@@ -9,6 +9,7 @@ These are the general environment variables used in the VCL:
* `SAL_NO_NWF` - disable native widgets
* `SAL_FORCEDPI` - force a specific DPI (gtk3 & qt5/kf5 plugins only)
* `SAL_FORCE_HC` - force high-contrast mode
+* `SAL_USE_SYSTEM_LOOP` - calls std::abort on nested event loop calls. Currently just for Qt with many crashes. WIP.
* `SAL_NO_FONT_LOOKUP` - disable font search and fallback and always use a hard-coded font name (for some unit tests)
diff --git a/vcl/inc/qt5/QtInstance.hxx b/vcl/inc/qt5/QtInstance.hxx
index 9c3adb25e98b..2d246c0bd92d 100644
--- a/vcl/inc/qt5/QtInstance.hxx
+++ b/vcl/inc/qt5/QtInstance.hxx
@@ -176,6 +176,7 @@ public:
void* CreateGStreamerSink(const SystemChildWindow*) override;
bool DoExecute(int& nExitCode) override;
+ void DoQuit() override;
};
inline QtInstance* GetQtInstance() { return static_cast<QtInstance*>(GetSalInstance()); }
diff --git a/vcl/inc/salinst.hxx b/vcl/inc/salinst.hxx
index 90367c06bcc9..084ab2e51c58 100644
--- a/vcl/inc/salinst.hxx
+++ b/vcl/inc/salinst.hxx
@@ -215,7 +215,9 @@ public:
// Note: we cannot make this a global variable, because it might be initialised BEFORE the putenv() call in cppunittester.
static bool IsRunningUnitTest() { return getenv("LO_TESTNAME") != nullptr; }
- virtual bool DoExecute(int & /* nExitCode */) { return false; }
+ // both must to be implemented, if the VCL plugin needs to run via system event loop
+ virtual bool DoExecute(int &nExitCode);
+ virtual void DoQuit();
};
// called from SVMain
diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx
index 89e4d67a3800..ae6e361cb079 100644
--- a/vcl/inc/svdata.hxx
+++ b/vcl/inc/svdata.hxx
@@ -133,6 +133,7 @@ typedef std::pair<VclPtr<vcl::Window>, ImplPostEventData *> ImplPostEventPair;
struct ImplSVAppData
{
+ ImplSVAppData();
~ImplSVAppData();
std::optional<AllSettings> mxSettings; // Application settings
@@ -159,6 +160,7 @@ struct ImplSVAppData
bool mbSettingsInit = false; // true: Settings are initialized
DialogCancelMode meDialogCancel = DialogCancelMode::Off; // true: All Dialog::Execute() calls will be terminated immediately with return false
bool mbRenderToBitmaps = false; // set via svp / headless plugin
+ bool m_bUseSystemLoop = false;
SvFileStream* mpEventTestInput = nullptr;
Idle* mpEventTestingIdle = nullptr;
diff --git a/vcl/qt5/QtInstance.cxx b/vcl/qt5/QtInstance.cxx
index a03b71e46bd2..a52f6529c3bc 100644
--- a/vcl/qt5/QtInstance.cxx
+++ b/vcl/qt5/QtInstance.cxx
@@ -259,6 +259,8 @@ QtInstance::QtInstance(std::unique_ptr<QApplication>& pQApp, bool bUseCairo)
#ifndef EMSCRIPTEN
m_bSupportsOpenGL = true;
+#else
+ ImplGetSVData()->maAppData.m_bUseSystemLoop = true;
#endif
}
@@ -726,13 +728,16 @@ std::unique_ptr<QApplication> QtInstance::CreateQApplication(int& nArgc, char**
bool QtInstance::DoExecute(int& nExitCode)
{
-#ifdef EMSCRIPTEN
- nExitCode = m_pQApplication->exec();
- return true;
-#else
- (void)nExitCode;
- return false;
-#endif
+ const bool bIsOnSystemEventLoop = Application::IsOnSystemEventLoop();
+ if (bIsOnSystemEventLoop)
+ nExitCode = QApplication::exec();
+ return bIsOnSystemEventLoop;
+}
+
+void QtInstance::DoQuit()
+{
+ if (Application::IsOnSystemEventLoop())
+ QApplication::quit();
}
extern "C" {
diff --git a/vcl/qt5/QtTimer.cxx b/vcl/qt5/QtTimer.cxx
index 6568ca8ac1b8..1a34213977dc 100644
--- a/vcl/qt5/QtTimer.cxx
+++ b/vcl/qt5/QtTimer.cxx
@@ -42,11 +42,12 @@ QtTimer::QtTimer()
void QtTimer::timeoutActivated()
{
SolarMutexGuard aGuard;
-#ifdef EMSCRIPTEN
- const ImplSVData* pSVData = ImplGetSVData();
- assert(pSVData->mpDefInst);
- static_cast<QtInstance*>(pSVData->mpDefInst)->DispatchUserEvents(true);
-#endif
+ if (Application::IsOnSystemEventLoop())
+ {
+ const ImplSVData* pSVData = ImplGetSVData();
+ assert(pSVData && pSVData->mpDefInst);
+ static_cast<QtInstance*>(pSVData->mpDefInst)->DispatchUserEvents(true);
+ }
CallCallback();
}
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index e19d055b8253..bfcd6834caac 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -142,6 +142,20 @@ bool SalInstance::CallEventCallback(void const* pEvent, int nBytes)
return m_pEventInst.is() && m_pEventInst->dispatchEvent(pEvent, nBytes);
}
+bool SalInstance::DoExecute(int&)
+{
+ // can't run on system event loop without implementing DoExecute and DoQuit
+ if (Application::IsOnSystemEventLoop())
+ std::abort();
+ return false;
+}
+
+void SalInstance::DoQuit()
+{
+ if (Application::IsOnSystemEventLoop())
+ std::abort();
+}
+
SalTimer::~SalTimer() COVERITY_NOEXCEPT_FALSE {}
void SalBitmap::DropScaledCache()
diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx
index c1f3b4a5bccf..cc046decdad5 100644
--- a/vcl/source/app/svapp.cxx
+++ b/vcl/source/app/svapp.cxx
@@ -443,6 +443,11 @@ void Application::Execute()
int nExitCode = 0;
if (!pSVData->mpDefInst->DoExecute(nExitCode))
{
+ if (Application::IsOnSystemEventLoop())
+ {
+ SAL_WARN("vcl.schedule", "Can't omit DoExecute when running on system event loop!");
+ std::abort();
+ }
while (!pSVData->maAppData.mbAppQuit)
Application::Yield();
}
@@ -452,7 +457,6 @@ void Application::Execute()
GetpApp()->Shutdown();
}
-#ifndef EMSCRIPTEN
static bool ImplYield(bool i_bWait, bool i_bAllEvents)
{
ImplSVData* pSVData = ImplGetSVData();
@@ -477,23 +481,27 @@ static bool ImplYield(bool i_bWait, bool i_bAllEvents)
SAL_INFO("vcl.schedule", "Leave ImplYield with return " << bProcessedEvent );
return bProcessedEvent;
}
-#endif
bool Application::Reschedule( bool i_bAllEvents )
{
-#ifdef EMSCRIPTEN
- SAL_WARN("wasm", "Application::Reschedule(" << i_bAllEvents << ")");
- (void) i_bAllEvents;
- std::abort();
-#else
+ static const bool bAbort = Application::IsOnSystemEventLoop();
+ if (bAbort)
+ {
+ SAL_WARN("vcl.schedule", "Application::Reschedule(" << i_bAllEvents << ")");
+ std::abort();
+ }
return ImplYield(false, i_bAllEvents);
-#endif
+}
+
+bool Application::IsOnSystemEventLoop()
+{
+ return ImplGetSVData()->maAppData.m_bUseSystemLoop;
}
void Scheduler::ProcessEventsToIdle()
{
int nSanity = 1;
- while( Application::Reschedule( true ) )
+ while (ImplYield(false, true))
{
if (0 == ++nSanity % 1000)
{
@@ -541,17 +549,19 @@ SAL_DLLPUBLIC_EXPORT void unit_lok_process_events_to_idle()
void Application::Yield()
{
-#ifdef EMSCRIPTEN
- SAL_WARN("wasm", "Application::Yield()");
- std::abort();
-#else
+ static const bool bAbort = Application::IsOnSystemEventLoop();
+ if (bAbort)
+ {
+ SAL_WARN("vcl.schedule", "Application::Yield()");
+ std::abort();
+ }
ImplYield(true, false);
-#endif
}
IMPL_STATIC_LINK_NOARG( ImplSVAppData, ImplQuitMsg, void*, void )
{
assert(ImplGetSVData()->maAppData.mbAppQuit);
+ ImplGetSVData()->mpDefInst->DoQuit();
}
void Application::Quit()
diff --git a/vcl/source/app/svdata.cxx b/vcl/source/app/svdata.cxx
index f91e1fe67fa9..7ba785277c3e 100644
--- a/vcl/source/app/svdata.cxx
+++ b/vcl/source/app/svdata.cxx
@@ -474,6 +474,13 @@ ImplSVHelpData& ImplGetSVHelpData()
}
ImplSVData::~ImplSVData() {}
+
+ImplSVAppData::ImplSVAppData()
+{
+ m_bUseSystemLoop = getenv("SAL_USE_SYSTEM_LOOP") != nullptr;
+ SAL_WARN_IF(m_bUseSystemLoop, "vcl.schedule", "Overriding to run LO on system event loop!");
+}
+
ImplSVAppData::~ImplSVAppData() {}
ImplSVGDIData::~ImplSVGDIData() {}
ImplSVFrameData::~ImplSVFrameData() {}