[Libreoffice-commits] core.git: Branch 'libreoffice-5-3' - sd/inc sd/source

Michael Stahl mstahl at redhat.com
Mon Jan 16 11:33:40 UTC 2017


 sd/inc/sdmod.hxx                                     |    5 --
 sd/source/ui/app/sdmod.cxx                           |    4 -
 sd/source/ui/inc/tools/SdGlobalResourceContainer.hxx |    2 
 sd/source/ui/tools/SdGlobalResourceContainer.cxx     |   41 ++++++++++++-------
 4 files changed, 29 insertions(+), 23 deletions(-)

New commits:
commit 821b9ee9ba4ab13c3525009eb7e6a8fd60176dd7
Author: Michael Stahl <mstahl at redhat.com>
Date:   Fri Jan 13 00:16:02 2017 +0100

    tdf#105188 sd: fix shutdown crash after accessing master pages
    
    The problem here is that the destructor of SdModule does a lot of
    things, including destroying an SdXImpressDocument that is referenced
    from some SdGlobalResourceContainer.
    
    This calls SD_MOD() to get the SdModule to get some resource, but at
    that point SfxApplication::GetModule() returns null, because the
    sequence was changed from first deleting the SfxModules, then clearing
    the pointer in ~SfxModule to null, to unique_ptr::reset(), which, at
    least in libstdc++, is implemented via std::swap, so it clears the
    pointer before deleting the SfxModule.
    
    It appears rather brittle to rely on such a subtle detail, so refactor
    things so that SdGlobalResourceContainer is no longer owned by SdModule
    but has its own pet XTerminationListener, which means it will be
    destroyed earlier, while the SdModule is still fully alive.
    
    (regression from f7b1cd66167050afecf487e3d89ea12de74200b5)
    
    Change-Id: I7f03f3adf431be8728ef3d65a078b536cb96f959
    (cherry picked from commit 983ac87793a891855c7d25c42fe795908543716c)
    Reviewed-on: https://gerrit.libreoffice.org/33033
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>

diff --git a/sd/inc/sdmod.hxx b/sd/inc/sdmod.hxx
index 6a8f735..c96a1b1 100644
--- a/sd/inc/sdmod.hxx
+++ b/sd/inc/sdmod.hxx
@@ -47,7 +47,6 @@ namespace svtools { class ColorConfig; }
 
 namespace sd {
 class DrawDocShell;
-class SdGlobalResourceContainer;
 }
 
 namespace com { namespace sun { namespace star { namespace frame {
@@ -156,10 +155,6 @@ private:
     static SfxFrame* CreateEmptyDocument( const css::uno::Reference< css::frame::XFrame >& i_rFrame );
     static SfxFrame* CreateFromTemplate( const OUString& rTemplatePath, const css::uno::Reference< css::frame::XFrame >& i_rFrame );
 
-    /** The resource container controls the lifetime of some singletons.
-    */
-    ::std::unique_ptr< ::sd::SdGlobalResourceContainer> mpResourceContainer;
-
     bool mbEventListenerAdded;
 
     /** Take an outline from a text document and create a new impress
diff --git a/sd/source/ui/app/sdmod.cxx b/sd/source/ui/app/sdmod.cxx
index d5cfa2a..067db17 100644
--- a/sd/source/ui/app/sdmod.cxx
+++ b/sd/source/ui/app/sdmod.cxx
@@ -53,7 +53,6 @@
 #include "strings.hrc"
 #include "res_bmp.hrc"
 #include "cfgids.hxx"
-#include "tools/SdGlobalResourceContainer.hxx"
 
 
 #define SdModule
@@ -77,7 +76,6 @@ SdModule::SdModule(SfxObjectFactory* pFact1, SfxObjectFactory* pFact2 )
     pSearchItem(nullptr),
     pNumberFormatter( nullptr ),
     bWaterCan(false),
-    mpResourceContainer(new ::sd::SdGlobalResourceContainer()),
     mbEventListenerAdded(false),
     mpColorConfig(new svtools::ColorConfig)
 {
@@ -110,8 +108,6 @@ SdModule::~SdModule()
         Application::RemoveEventListener( LINK( this, SdModule, EventListenerHdl ) );
     }
 
-    mpResourceContainer.reset();
-
     delete mpErrorHdl;
     mpVirtualRefDevice.disposeAndClear();
 }
diff --git a/sd/source/ui/inc/tools/SdGlobalResourceContainer.hxx b/sd/source/ui/inc/tools/SdGlobalResourceContainer.hxx
index e1c483e..c8afe89 100644
--- a/sd/source/ui/inc/tools/SdGlobalResourceContainer.hxx
+++ b/sd/source/ui/inc/tools/SdGlobalResourceContainer.hxx
@@ -82,7 +82,7 @@ public:
     void AddResource (const css::uno::Reference<css::uno::XInterface>& rxResource);
 
 protected:
-    friend class ::SdModule;
+    friend class SdGlobalResourceContainerInstance;
     friend struct ::std::default_delete<SdGlobalResourceContainer>;
 
     class Implementation;
diff --git a/sd/source/ui/tools/SdGlobalResourceContainer.cxx b/sd/source/ui/tools/SdGlobalResourceContainer.cxx
index dadc8db..595f3f7 100644
--- a/sd/source/ui/tools/SdGlobalResourceContainer.cxx
+++ b/sd/source/ui/tools/SdGlobalResourceContainer.cxx
@@ -19,6 +19,13 @@
 
 #include "tools/SdGlobalResourceContainer.hxx"
 
+#include <comphelper/processfactory.hxx>
+#include <comphelper/unique_disposing_ptr.hxx>
+
+#include <com/sun/star/frame/Desktop.hpp>
+
+#include <rtl/instance.hxx>
+
 #include <algorithm>
 #include <vector>
 
@@ -27,13 +34,30 @@ using namespace ::com::sun::star::uno;
 
 namespace sd {
 
+class SdGlobalResourceContainerInstance
+    : public comphelper::unique_disposing_solar_mutex_reset_ptr<SdGlobalResourceContainer>
+{
+public:
+    SdGlobalResourceContainerInstance()
+        : comphelper::unique_disposing_solar_mutex_reset_ptr<SdGlobalResourceContainer>(
+            uno::Reference<lang::XComponent>(frame::Desktop::create(comphelper::getProcessComponentContext()), uno::UNO_QUERY_THROW),
+            new SdGlobalResourceContainer, true)
+    {
+    }
+};
+
+namespace {
+
+struct theSdGlobalResourceContainerInstance : public rtl::Static<SdGlobalResourceContainerInstance, theSdGlobalResourceContainerInstance> {};
+
+} // namespace
+
 //===== SdGlobalResourceContainer::Implementation =============================
 
 class SdGlobalResourceContainer::Implementation
 {
 private:
     friend class SdGlobalResourceContainer;
-    static SdGlobalResourceContainer* mpInstance;
 
     ::osl::Mutex maMutex;
 
@@ -53,15 +77,11 @@ private:
 // static
 SdGlobalResourceContainer& SdGlobalResourceContainer::Instance()
 {
-    DBG_ASSERT(Implementation::mpInstance!=nullptr,
-        "SdGlobalResourceContainer::Instance(): instance has been deleted");
-    // Maybe we should throw an exception when the instance has been deleted.
-    return *Implementation::mpInstance;
+    SdGlobalResourceContainer *const pRet(theSdGlobalResourceContainerInstance::get().get());
+    assert(pRet); // error if it has been deleted and is null
+    return *pRet;
 }
 
-SdGlobalResourceContainer*
-    SdGlobalResourceContainer::Implementation::mpInstance = nullptr;
-
 //===== SdGlobalResourceContainer =============================================
 
 void SdGlobalResourceContainer::AddResource (
@@ -128,7 +148,6 @@ void SdGlobalResourceContainer::AddResource (const Reference<XInterface>& rxReso
 SdGlobalResourceContainer::SdGlobalResourceContainer()
     : mpImpl (new SdGlobalResourceContainer::Implementation())
 {
-    Implementation::mpInstance = this;
 }
 
 SdGlobalResourceContainer::~SdGlobalResourceContainer()
@@ -174,10 +193,6 @@ SdGlobalResourceContainer::~SdGlobalResourceContainer()
         if (xComponent.is())
             xComponent->dispose();
     }
-
-    DBG_ASSERT(Implementation::mpInstance == this,
-        "~SdGlobalResourceContainer(): more than one instance of singleton");
-    Implementation::mpInstance = nullptr;
 }
 
 } // end of namespace sd


More information about the Libreoffice-commits mailing list