diff options
-rw-r--r-- | basctl/source/basicide/iderdll.cxx | 2 | ||||
-rw-r--r-- | framework/inc/services/desktop.hxx | 2 | ||||
-rw-r--r-- | framework/source/services/desktop.cxx | 29 | ||||
-rw-r--r-- | include/comphelper/unique_disposing_ptr.hxx | 40 | ||||
-rw-r--r-- | 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<Dll> { public: - DllInstance() : comphelper::unique_disposing_solar_mutex_reset_ptr<Dll>(Reference<lang::XComponent>( frame::Desktop::create(comphelper::getProcessComponentContext()), UNO_QUERY_THROW), new Dll) + DllInstance() : comphelper::unique_disposing_solar_mutex_reset_ptr<Dll>(Reference<lang::XComponent>( 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<css::uno::Reference<css::frame::XTerminateListener>> 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<css::frame::XTerminateListener> > 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<css::frame::XTerminateListener> > 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 <com/sun/star/lang/XComponent.hpp> #include <com/sun/star/frame/XDesktop.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> #include <vcl/svapp.hxx> #include <osl/mutex.hxx> @@ -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<T>& m_rItem; + bool mbComponentDLL; public: TerminateListener(const css::uno::Reference< css::lang::XComponent > &rComponent, - unique_disposing_ptr<T>& rItem) : m_xComponent(rComponent), m_rItem(rItem) + unique_disposing_ptr<T>& 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<OUString> SAL_CALL getSupportedServiceNames() + throw (css::uno::RuntimeException, std::exception) override + { + return css::uno::Sequence<OUString>(); + } }; }; @@ -141,8 +167,8 @@ template<class T> class unique_disposing_solar_mutex_reset_ptr : public unique_disposing_ptr<T> { public: - unique_disposing_solar_mutex_reset_ptr( const css::uno::Reference< css::lang::XComponent > &rComponent, T * p = nullptr ) - : unique_disposing_ptr<T>(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<T>(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<SwDLL> { public: - SwDLLInstance() : comphelper::unique_disposing_solar_mutex_reset_ptr<SwDLL>(uno::Reference<lang::XComponent>( frame::Desktop::create(comphelper::getProcessComponentContext()), uno::UNO_QUERY_THROW), new SwDLL) + SwDLLInstance() : comphelper::unique_disposing_solar_mutex_reset_ptr<SwDLL>(uno::Reference<lang::XComponent>( frame::Desktop::create(comphelper::getProcessComponentContext()), uno::UNO_QUERY_THROW), new SwDLL, true) { } }; |