Kaydet (Commit) 2f0020ba authored tarafından Markus Mohrhard's avatar Markus Mohrhard Kaydeden (comit) Michael Stahl

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/32856Reviewed-by: 's avatarNoel Grandin <noel.grandin@collabora.co.uk>
Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarMarkus Mohrhard <markus.mohrhard@googlemail.com>
(cherry picked from commit ad915faf)
Reviewed-on: https://gerrit.libreoffice.org/32928Reviewed-by: 's avatarMichael Meeks <michael.meeks@collabora.com>
Reviewed-by: 's avatarMichael Stahl <mstahl@redhat.com>
üst 3defbf74
......@@ -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)
{ }
};
......
......@@ -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
......
......@@ -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();
......
......@@ -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)
{
}
......
......@@ -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)
{
}
};
......
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