summaryrefslogtreecommitdiff
path: root/sd/source/ui
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2017-01-13 00:16:02 +0100
committerMichael Stahl <mstahl@redhat.com>2017-01-13 00:27:15 +0100
commit983ac87793a891855c7d25c42fe795908543716c (patch)
tree8d815f2710d8c9868d73117540e7f44b72799a8e /sd/source/ui
parent349a3c073391842e94ee83345e9c2f38339be1d7 (diff)
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
Diffstat (limited to 'sd/source/ui')
-rw-r--r--sd/source/ui/app/sdmod.cxx4
-rw-r--r--sd/source/ui/inc/tools/SdGlobalResourceContainer.hxx2
-rw-r--r--sd/source/ui/tools/SdGlobalResourceContainer.cxx41
3 files changed, 29 insertions, 18 deletions
diff --git a/sd/source/ui/app/sdmod.cxx b/sd/source/ui/app/sdmod.cxx
index ebef895ad347..bd0249929db0 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 e1c483eec439..c8afe89a2f9a 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 a7f0d54cac34..14653553ec67 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