From 2f0020ba056e2b523c487dc42b40f0e4b9f9a9b0 Mon Sep 17 00:00:00 2001 From: Markus Mohrhard Date: Mon, 9 Jan 2017 05:58:00 +0100 Subject: tdf#104830, need an own termination listener for lib objects The destruction of the SwDLL object happens already through the normal termination listener but the other termination listeners might still depend on it. Also the outstanding events might need the SwDLL instance to be still around. This makes the destruction of the instance explicit and at a time when it should be safe. We should use the same code for calc, impress, math and base as well. Change-Id: I50b8f30426f5a4a54e362e748fe962839abca73e Reviewed-on: https://gerrit.libreoffice.org/32856 Reviewed-by: Noel Grandin Tested-by: Jenkins Reviewed-by: Markus Mohrhard (cherry picked from commit ad915fafd54f9115faea7147f82d80a942af2d68) Reviewed-on: https://gerrit.libreoffice.org/32928 Reviewed-by: Michael Meeks Reviewed-by: Michael Stahl --- basctl/source/basicide/iderdll.cxx | 2 +- framework/inc/services/desktop.hxx | 2 ++ framework/source/services/desktop.cxx | 29 +++++++++++++++++++++ include/comphelper/unique_disposing_ptr.hxx | 40 ++++++++++++++++++++++++----- sw/source/uibase/app/swdll.cxx | 2 +- 5 files changed, 66 insertions(+), 9 deletions(-) diff --git a/basctl/source/basicide/iderdll.cxx b/basctl/source/basicide/iderdll.cxx index 19d5961eb93b..d155780e22ed 100644 --- a/basctl/source/basicide/iderdll.cxx +++ b/basctl/source/basicide/iderdll.cxx @@ -63,7 +63,7 @@ public: class DllInstance : public comphelper::unique_disposing_solar_mutex_reset_ptr { public: - DllInstance() : comphelper::unique_disposing_solar_mutex_reset_ptr(Reference( frame::Desktop::create(comphelper::getProcessComponentContext()), UNO_QUERY_THROW), new Dll) + DllInstance() : comphelper::unique_disposing_solar_mutex_reset_ptr(Reference( frame::Desktop::create(comphelper::getProcessComponentContext()), UNO_QUERY_THROW), new Dll, true) { } }; diff --git a/framework/inc/services/desktop.hxx b/framework/inc/services/desktop.hxx index e8fd0017d628..bd766e8fdc5f 100644 --- a/framework/inc/services/desktop.hxx +++ b/framework/inc/services/desktop.hxx @@ -454,6 +454,8 @@ class Desktop : private cppu::BaseMutex, css::uno::Reference< css::frame::XUntitledNumbers > m_xTitleNumberGenerator; + std::vector> m_xComponentDllListeners; + }; // class Desktop } // namespace framework diff --git a/framework/source/services/desktop.cxx b/framework/source/services/desktop.cxx index 3e5f3a0242bc..18eecb3a3ead 100644 --- a/framework/source/services/desktop.cxx +++ b/framework/source/services/desktop.cxx @@ -335,6 +335,14 @@ sal_Bool SAL_CALL Desktop::terminate() if ( xPipeTerminator.is() ) xPipeTerminator->notifyTermination( aEvent ); + // we need a copy here as the notifyTermination call might cause a removeTerminateListener call + std::vector< css::uno::Reference > xComponentDllListeners = m_xComponentDllListeners; + for (auto& xListener : xComponentDllListeners) + { + xListener->notifyTermination(aEvent); + } + m_xComponentDllListeners.clear(); + // Must be really the last listener to be called. // Because it shutdown the whole process asynchronous ! if ( xSfxTerminator.is() ) @@ -407,6 +415,11 @@ void SAL_CALL Desktop::addTerminateListener( const css::uno::Reference< css::fra m_xSWThreadManager = xListener; return; } + else if ( sImplementationName == "com.sun.star.comp.ComponentDLLListener" ) + { + m_xComponentDllListeners.push_back(xListener); + return; + } } // No lock required ... container is threadsafe by itself. @@ -448,6 +461,13 @@ void SAL_CALL Desktop::removeTerminateListener( const css::uno::Reference< css:: m_xSWThreadManager.clear(); return; } + else if (sImplementationName == "com.sun.star.comp.ComponentDLLListener") + { + m_xComponentDllListeners.erase( + std::remove(m_xComponentDllListeners.begin(), m_xComponentDllListeners.end(), xListener), + m_xComponentDllListeners.end()); + return; + } } // No lock required ... container is threadsafe by itself. @@ -1076,6 +1096,15 @@ void SAL_CALL Desktop::disposing() m_xPipeTerminator.clear(); m_xQuickLauncher.clear(); m_xSWThreadManager.clear(); + + // we need a copy because the notifyTermination might call the removeEventListener method + std::vector< css::uno::Reference > xComponentDllListeners = m_xComponentDllListeners; + for (auto& xListener: xComponentDllListeners) + { + xListener->notifyTermination(aEvent); + } + xComponentDllListeners.clear(); + m_xComponentDllListeners.clear(); m_xSfxTerminator.clear(); m_xCommandOptions.reset(); diff --git a/include/comphelper/unique_disposing_ptr.hxx b/include/comphelper/unique_disposing_ptr.hxx index 0f120b179392..64ff5402b5b6 100644 --- a/include/comphelper/unique_disposing_ptr.hxx +++ b/include/comphelper/unique_disposing_ptr.hxx @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -30,10 +31,10 @@ private: unique_disposing_ptr(const unique_disposing_ptr&) = delete; unique_disposing_ptr& operator=(const unique_disposing_ptr&) = delete; public: - unique_disposing_ptr( const css::uno::Reference< css::lang::XComponent > &rComponent, T * p = nullptr ) + unique_disposing_ptr( const css::uno::Reference< css::lang::XComponent > &rComponent, T * p = nullptr, bool bComponent = false) : m_xItem(p) { - m_xTerminateListener = new TerminateListener(rComponent, *this); + m_xTerminateListener = new TerminateListener(rComponent, *this, bComponent); } virtual void reset(T * p = nullptr) @@ -66,14 +67,19 @@ public: reset(); } private: - class TerminateListener : public ::cppu::WeakImplHelper< css::frame::XTerminateListener > + class TerminateListener : public ::cppu::WeakImplHelper< css::frame::XTerminateListener, + css::lang::XServiceInfo> { private: css::uno::Reference< css::lang::XComponent > m_xComponent; unique_disposing_ptr& m_rItem; + bool mbComponentDLL; public: TerminateListener(const css::uno::Reference< css::lang::XComponent > &rComponent, - unique_disposing_ptr& rItem) : m_xComponent(rComponent), m_rItem(rItem) + unique_disposing_ptr& rItem, bool bComponentDLL) : + m_xComponent(rComponent), + m_rItem(rItem), + mbComponentDLL(bComponentDLL) { if (m_xComponent.is()) { @@ -97,7 +103,6 @@ private: } } - private: // XEventListener virtual void SAL_CALL disposing( const css::lang::EventObject& rEvt ) throw (css::uno::RuntimeException, std::exception) override @@ -130,6 +135,27 @@ private: { disposing(rEvt); } + + virtual OUString SAL_CALL getImplementationName() + throw (css::uno::RuntimeException, std::exception) override + { + if (mbComponentDLL) + return OUString("com.sun.star.comp.ComponentDLLListener"); + else + return OUString("com.sun.star.comp.DisposingTerminateListener"); + } + + virtual sal_Bool SAL_CALL supportsService(const OUString& /*rName*/) + throw (css::uno::RuntimeException, std::exception) override + { + return false; + } + + virtual css::uno::Sequence SAL_CALL getSupportedServiceNames() + throw (css::uno::RuntimeException, std::exception) override + { + return css::uno::Sequence(); + } }; }; @@ -141,8 +167,8 @@ template class unique_disposing_solar_mutex_reset_ptr : public unique_disposing_ptr { public: - unique_disposing_solar_mutex_reset_ptr( const css::uno::Reference< css::lang::XComponent > &rComponent, T * p = nullptr ) - : unique_disposing_ptr(rComponent, p) + unique_disposing_solar_mutex_reset_ptr( const css::uno::Reference< css::lang::XComponent > &rComponent, T * p = nullptr, bool bComponent = false) + : unique_disposing_ptr(rComponent, p, bComponent) { } diff --git a/sw/source/uibase/app/swdll.cxx b/sw/source/uibase/app/swdll.cxx index 803c2b8cc376..ed4d3fa0a782 100644 --- a/sw/source/uibase/app/swdll.cxx +++ b/sw/source/uibase/app/swdll.cxx @@ -58,7 +58,7 @@ namespace class SwDLLInstance : public comphelper::unique_disposing_solar_mutex_reset_ptr { public: - SwDLLInstance() : comphelper::unique_disposing_solar_mutex_reset_ptr(uno::Reference( frame::Desktop::create(comphelper::getProcessComponentContext()), uno::UNO_QUERY_THROW), new SwDLL) + SwDLLInstance() : comphelper::unique_disposing_solar_mutex_reset_ptr(uno::Reference( frame::Desktop::create(comphelper::getProcessComponentContext()), uno::UNO_QUERY_THROW), new SwDLL, true) { } }; -- cgit v1.2.3