summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Mohrhard <markus.mohrhard@googlemail.com>2017-01-09 05:58:00 +0100
committerMarkus Mohrhard <markus.mohrhard@googlemail.com>2017-01-10 13:23:43 +0000
commitad915fafd54f9115faea7147f82d80a942af2d68 (patch)
treec119ea25cc8e07f337af9f280a19c32d63ecb701
parent11e5668f12565ad9b1acb5c0085653c7a22ca329 (diff)
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 <noel.grandin@collabora.co.uk> Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Markus Mohrhard <markus.mohrhard@googlemail.com>
-rw-r--r--basctl/source/basicide/iderdll.cxx2
-rw-r--r--framework/inc/services/desktop.hxx2
-rw-r--r--framework/source/services/desktop.cxx29
-rw-r--r--include/comphelper/unique_disposing_ptr.hxx40
-rw-r--r--sw/source/uibase/app/swdll.cxx2
5 files changed, 66 insertions, 9 deletions
diff --git a/basctl/source/basicide/iderdll.cxx b/basctl/source/basicide/iderdll.cxx
index b301ef73742b..1faeb46ae634 100644
--- a/basctl/source/basicide/iderdll.cxx
+++ b/basctl/source/basicide/iderdll.cxx
@@ -61,7 +61,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 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<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 9ab71a9f32a2..22a8360d5335 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<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() )
@@ -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<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 75be7d6dabec..c986b12e316f 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 e9fa7f196e31..d621e4783bfb 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)
{
}
};