From baa91265d38ac44294b93f8ce47162454fbeb6d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= Date: Mon, 8 May 2017 15:26:22 +0100 Subject: [PATCH] Resolves: rhbz#144437 make gnome-documents not crash the whole time accept that once initted that LibreOffice cannot be deinitted and reinited (without lots of work), but allow the main loop to quit and restart so LOKs thread can run and exit successfully, new LOK connections will restart the main loop. The buckets of global state continues to be valid the whole time this way Change-Id: Ide54c0df2ce4065f7c192ae8c2cedfaaa2b58d72 --- desktop/source/app/app.cxx | 2 +- desktop/source/app/officeipcthread.cxx | 11 ++++++++--- desktop/source/app/officeipcthread.hxx | 2 +- desktop/source/lib/init.cxx | 6 ++++++ framework/source/services/desktop.cxx | 10 ++++++++-- libreofficekit/source/gtk/lokdocview.cxx | 6 ++++++ vcl/source/app/svapp.cxx | 1 + vcl/source/app/svmain.cxx | 8 ++++++++ 8 files changed, 39 insertions(+), 7 deletions(-) diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx index 5042752..372f605 100644 --- a/desktop/source/app/app.cxx +++ b/desktop/source/app/app.cxx @@ -1890,7 +1890,7 @@ IMPL_LINK_NOARG(Desktop, OpenClients_Impl) try { OpenClients(); - OfficeIPCThread::SetReady(); + OfficeIPCThread::SetReady(true); CloseSplashScreen(); CheckFirstRun( ); diff --git a/desktop/source/app/officeipcthread.cxx b/desktop/source/app/officeipcthread.cxx index cb6ad0b..e65e935 100644 --- a/desktop/source/app/officeipcthread.cxx +++ b/desktop/source/app/officeipcthread.cxx @@ -646,13 +646,15 @@ void OfficeIPCThread::DisableOfficeIPCThread(bool join) // release mutex to avoid deadlocks aMutex.clear(); - OfficeIPCThread::SetReady(pOfficeIPCThread); + OfficeIPCThread::SetReady(true, pOfficeIPCThread); // exit gracefully and join if (join) { pOfficeIPCThread->join(); } + + OfficeIPCThread::SetReady(false, pOfficeIPCThread); } } @@ -675,14 +677,17 @@ OfficeIPCThread::~OfficeIPCThread() pGlobalOfficeIPCThread.clear(); } -void OfficeIPCThread::SetReady( +void OfficeIPCThread::SetReady(bool bIsReady, rtl::Reference< OfficeIPCThread > const & pThread) { rtl::Reference< OfficeIPCThread > const & t( pThread.is() ? pThread : pGlobalOfficeIPCThread); if (t.is()) { - t->cReady.set(); + if (bIsReady) + t->cReady.set(); + else + t->cReady.reset(); } } diff --git a/desktop/source/app/officeipcthread.hxx b/desktop/source/app/officeipcthread.hxx index e81f57a..f23eff2 100644 --- a/desktop/source/app/officeipcthread.hxx +++ b/desktop/source/app/officeipcthread.hxx @@ -115,7 +115,7 @@ class OfficeIPCThread : public salhelper::Thread static Status EnableOfficeIPCThread(); static void DisableOfficeIPCThread(bool join = true); // start dispatching events... - static void SetReady( + static void SetReady(bool bIsReady, rtl::Reference< OfficeIPCThread > const & pThread = rtl::Reference< OfficeIPCThread >()); static void WaitForReady( diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 184d777..2619539 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -1697,7 +1697,12 @@ static void lo_startmain(void*) { osl_setThreadName("lo_startmain"); + if (comphelper::SolarMutex::get()) + Application::GetSolarMutex().tryToAcquire(); + soffice_main(); + + Application::ReleaseSolarMutex(); } static bool bInitialized = false; @@ -1799,6 +1804,7 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char SAL_INFO("lok", "Enabling OfficeIPCThread"); OfficeIPCThread::EnableOfficeIPCThread(); SAL_INFO("lok", "Starting soffice_main"); + OfficeIPCThread::SetReady(false); pLib->maThread = osl_createThread(lo_startmain, NULL); SAL_INFO("lok", "Waiting for OfficeIPCThread"); OfficeIPCThread::WaitForReady(); diff --git a/framework/source/services/desktop.cxx b/framework/source/services/desktop.cxx index 24b9761..c7dbaca 100644 --- a/framework/source/services/desktop.cxx +++ b/framework/source/services/desktop.cxx @@ -59,6 +59,7 @@ #include #include +#include #include #include @@ -231,8 +232,13 @@ sal_Bool SAL_CALL Desktop::terminate() // try to close all open frames. // Allow using of any UI ... because Desktop.terminate() was designed as UI functionality in the past. - bool bAllowUI = true; - bool bFramesClosed = impl_closeFrames(bAllowUI); + bool bRestartableMainLoop = comphelper::LibreOfficeKit::isActive(); + bool bFramesClosed = impl_closeFrames(!bRestartableMainLoop); + if (bRestartableMainLoop) + { + Application::Quit(); + return true; + } if ( ! bFramesClosed ) { impl_sendCancelTerminationEvent(lCalledTerminationListener); diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx index 7d1ec01..92cf6b3 100644 --- a/libreofficekit/source/gtk/lokdocview.cxx +++ b/libreofficekit/source/gtk/lokdocview.cxx @@ -2051,9 +2051,15 @@ static void lok_doc_view_destroy (GtkWidget* widget) LOKDocViewPrivate& priv = getPrivate(pDocView); if (priv->m_pDocument) + { priv->m_pDocument->pClass->destroy (priv->m_pDocument); + priv->m_pDocument = nullptr; + } if (priv->m_pOffice) + { priv->m_pOffice->pClass->destroy (priv->m_pOffice); + priv->m_pOffice = nullptr; + } GTK_WIDGET_CLASS (lok_doc_view_parent_class)->destroy (widget); } diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx index 302c4a7..2104243 100644 --- a/vcl/source/app/svapp.cxx +++ b/vcl/source/app/svapp.cxx @@ -331,6 +331,7 @@ void Application::Execute() { ImplSVData* pSVData = ImplGetSVData(); pSVData->maAppData.mbInAppExecute = true; + pSVData->maAppData.mbAppQuit = false; while ( !pSVData->maAppData.mbAppQuit ) Application::Yield(); diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx index f6d4e25..16977d3 100644 --- a/vcl/source/app/svmain.cxx +++ b/vcl/source/app/svmain.cxx @@ -28,6 +28,7 @@ #include "tools/resmgr.hxx" #include "comphelper/processfactory.hxx" +#include "comphelper/lok.hxx" #include "unotools/syslocaleoptions.hxx" #include "vcl/svapp.hxx" @@ -343,6 +344,13 @@ VCLUnoWrapperDeleter::disposing(lang::EventObject const& /* rSource */) void DeInitVCL() { + //rhbz#1444437, when using LibreOffice like a library you can't realistically + //tear everything down and recreate them on the next call, there's too many + //(c++) singletons that point to stuff that gets deleted during shutdown + //which won't be recreated on restart. + if (comphelper::LibreOfficeKit::isActive()) + return; + ImplSVData* pSVData = ImplGetSVData(); pSVData->mbDeInit = true; -- 1.8.3.1