Blob Blame History Raw
From baa91265d38ac44294b93f8ce47162454fbeb6d4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
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 <com/sun/star/frame/XTerminateListener2.hpp>
 
 #include <comphelper/sequence.hxx>
+#include <comphelper/lok.hxx>
 #include <cppuhelper/supportsservice.hxx>
 #include <vcl/svapp.hxx>
 
@@ -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