From d1b8074ffe4b945a41e3ad9e1fb43332d78d73fb 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/32926 Reviewed-by: Markus Mohrhard Tested-by: Markus Mohrhard --- framework/inc/services/desktop.hxx | 2 ++ framework/source/services/desktop.cxx | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) (limited to 'framework') diff --git a/framework/inc/services/desktop.hxx b/framework/inc/services/desktop.hxx index 8aa56efaf9a8..2c88e32c501f 100644 --- a/framework/inc/services/desktop.hxx +++ b/framework/inc/services/desktop.hxx @@ -455,6 +455,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 2ee7336c0927..20afab1ef700 100644 --- a/framework/source/services/desktop.cxx +++ b/framework/source/services/desktop.cxx @@ -347,6 +347,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() ) @@ -424,6 +432,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. @@ -471,6 +484,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. @@ -1100,6 +1120,15 @@ void SAL_CALL Desktop::disposing() m_xQuickLauncher.clear(); m_xStarBasicQuitGuard.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(); -- cgit