Kaydet (Commit) 983ac877 authored tarafından Michael Stahl's avatar Michael Stahl

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 f7b1cd66)

Change-Id: I7f03f3adf431be8728ef3d65a078b536cb96f959
üst 349a3c07
...@@ -47,7 +47,6 @@ namespace svtools { class ColorConfig; } ...@@ -47,7 +47,6 @@ namespace svtools { class ColorConfig; }
namespace sd { namespace sd {
class DrawDocShell; class DrawDocShell;
class SdGlobalResourceContainer;
} }
namespace com { namespace sun { namespace star { namespace frame { namespace com { namespace sun { namespace star { namespace frame {
...@@ -156,10 +155,6 @@ private: ...@@ -156,10 +155,6 @@ private:
static SfxFrame* CreateEmptyDocument( const css::uno::Reference< css::frame::XFrame >& i_rFrame ); 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 ); 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; bool mbEventListenerAdded;
/** Take an outline from a text document and create a new impress /** Take an outline from a text document and create a new impress
......
...@@ -53,7 +53,6 @@ ...@@ -53,7 +53,6 @@
#include "strings.hrc" #include "strings.hrc"
#include "res_bmp.hrc" #include "res_bmp.hrc"
#include "cfgids.hxx" #include "cfgids.hxx"
#include "tools/SdGlobalResourceContainer.hxx"
#define SdModule #define SdModule
...@@ -77,7 +76,6 @@ SdModule::SdModule(SfxObjectFactory* pFact1, SfxObjectFactory* pFact2 ) ...@@ -77,7 +76,6 @@ SdModule::SdModule(SfxObjectFactory* pFact1, SfxObjectFactory* pFact2 )
pSearchItem(nullptr), pSearchItem(nullptr),
pNumberFormatter( nullptr ), pNumberFormatter( nullptr ),
bWaterCan(false), bWaterCan(false),
mpResourceContainer(new ::sd::SdGlobalResourceContainer()),
mbEventListenerAdded(false), mbEventListenerAdded(false),
mpColorConfig(new svtools::ColorConfig) mpColorConfig(new svtools::ColorConfig)
{ {
...@@ -110,8 +108,6 @@ SdModule::~SdModule() ...@@ -110,8 +108,6 @@ SdModule::~SdModule()
Application::RemoveEventListener( LINK( this, SdModule, EventListenerHdl ) ); Application::RemoveEventListener( LINK( this, SdModule, EventListenerHdl ) );
} }
mpResourceContainer.reset();
delete mpErrorHdl; delete mpErrorHdl;
mpVirtualRefDevice.disposeAndClear(); mpVirtualRefDevice.disposeAndClear();
} }
......
...@@ -82,7 +82,7 @@ public: ...@@ -82,7 +82,7 @@ public:
void AddResource (const css::uno::Reference<css::uno::XInterface>& rxResource); void AddResource (const css::uno::Reference<css::uno::XInterface>& rxResource);
protected: protected:
friend class ::SdModule; friend class SdGlobalResourceContainerInstance;
friend struct ::std::default_delete<SdGlobalResourceContainer>; friend struct ::std::default_delete<SdGlobalResourceContainer>;
class Implementation; class Implementation;
......
...@@ -19,6 +19,13 @@ ...@@ -19,6 +19,13 @@
#include "tools/SdGlobalResourceContainer.hxx" #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 <algorithm>
#include <vector> #include <vector>
...@@ -27,13 +34,30 @@ using namespace ::com::sun::star::uno; ...@@ -27,13 +34,30 @@ using namespace ::com::sun::star::uno;
namespace sd { 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 ============================= //===== SdGlobalResourceContainer::Implementation =============================
class SdGlobalResourceContainer::Implementation class SdGlobalResourceContainer::Implementation
{ {
private: private:
friend class SdGlobalResourceContainer; friend class SdGlobalResourceContainer;
static SdGlobalResourceContainer* mpInstance;
::osl::Mutex maMutex; ::osl::Mutex maMutex;
...@@ -53,15 +77,11 @@ private: ...@@ -53,15 +77,11 @@ private:
// static // static
SdGlobalResourceContainer& SdGlobalResourceContainer::Instance() SdGlobalResourceContainer& SdGlobalResourceContainer::Instance()
{ {
DBG_ASSERT(Implementation::mpInstance!=nullptr, SdGlobalResourceContainer *const pRet(theSdGlobalResourceContainerInstance::get().get());
"SdGlobalResourceContainer::Instance(): instance has been deleted"); assert(pRet); // error if it has been deleted and is null
// Maybe we should throw an exception when the instance has been deleted. return *pRet;
return *Implementation::mpInstance;
} }
SdGlobalResourceContainer*
SdGlobalResourceContainer::Implementation::mpInstance = nullptr;
//===== SdGlobalResourceContainer ============================================= //===== SdGlobalResourceContainer =============================================
void SdGlobalResourceContainer::AddResource ( void SdGlobalResourceContainer::AddResource (
...@@ -128,7 +148,6 @@ void SdGlobalResourceContainer::AddResource (const Reference<XInterface>& rxReso ...@@ -128,7 +148,6 @@ void SdGlobalResourceContainer::AddResource (const Reference<XInterface>& rxReso
SdGlobalResourceContainer::SdGlobalResourceContainer() SdGlobalResourceContainer::SdGlobalResourceContainer()
: mpImpl (new SdGlobalResourceContainer::Implementation()) : mpImpl (new SdGlobalResourceContainer::Implementation())
{ {
Implementation::mpInstance = this;
} }
SdGlobalResourceContainer::~SdGlobalResourceContainer() SdGlobalResourceContainer::~SdGlobalResourceContainer()
...@@ -174,10 +193,6 @@ SdGlobalResourceContainer::~SdGlobalResourceContainer() ...@@ -174,10 +193,6 @@ SdGlobalResourceContainer::~SdGlobalResourceContainer()
if (xComponent.is()) if (xComponent.is())
xComponent->dispose(); xComponent->dispose();
} }
DBG_ASSERT(Implementation::mpInstance == this,
"~SdGlobalResourceContainer(): more than one instance of singleton");
Implementation::mpInstance = nullptr;
} }
} // end of namespace sd } // end of namespace sd
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment