diff options
author | Caolán McNamara <caolanm@redhat.com> | 2016-08-27 21:32:39 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2016-08-28 10:01:11 +0000 |
commit | 45e01be11111213f689ba5f1fa319e3dc48ea9c5 (patch) | |
tree | b90c7eee32baf97acd2f62b4a7ae20d199d548fe /connectivity | |
parent | 5bdea25f681fb252967f99a22a38cce6be3c0b48 (diff) |
Resolves: tdf#81883 dispose OCalcConnection's doc before shutdown
if noone else does it, then ensure the doc is disposed before
XDesktop it torn down
Change-Id: I3136802a40c9cfb43039307dc65949d3264b6f2b
Reviewed-on: https://gerrit.libreoffice.org/28428
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'connectivity')
-rw-r--r-- | connectivity/source/drivers/calc/CConnection.cxx | 16 | ||||
-rw-r--r-- | connectivity/source/inc/calc/CConnection.hxx | 68 |
2 files changed, 77 insertions, 7 deletions
diff --git a/connectivity/source/drivers/calc/CConnection.cxx b/connectivity/source/drivers/calc/CConnection.cxx index 3934fd4c2861..a315bc6b7c45 100644 --- a/connectivity/source/drivers/calc/CConnection.cxx +++ b/connectivity/source/drivers/calc/CConnection.cxx @@ -31,7 +31,6 @@ #include "calc/CPreparedStatement.hxx" #include "calc/CStatement.hxx" #include <unotools/pathoptions.hxx> -#include <unotools/closeveto.hxx> #include <connectivity/dbexception.hxx> #include <cppuhelper/exc_hlp.hxx> #include <comphelper/processfactory.hxx> @@ -164,7 +163,8 @@ Reference< XSpreadsheetDocument> const & OCalcConnection::acquireDoc() ::dbtools::throwGenericSQLException( sError, *this, aErrorDetails ); } osl_atomic_increment(&m_nDocCount); - m_pCloseListener.reset(new utl::CloseVeto(m_xDoc, true)); + m_xCloseVetoButTerminateListener.set(new CloseVetoButTerminateListener); + m_xCloseVetoButTerminateListener->start(m_xDoc, xDesktop); return m_xDoc; } @@ -172,7 +172,11 @@ void OCalcConnection::releaseDoc() { if ( osl_atomic_decrement(&m_nDocCount) == 0 ) { - m_pCloseListener.reset(); // dispose m_xDoc + if (m_xCloseVetoButTerminateListener.is()) + { + m_xCloseVetoButTerminateListener->stop(); // dispose m_xDoc + m_xCloseVetoButTerminateListener.clear(); + } m_xDoc.clear(); } } @@ -182,7 +186,11 @@ void OCalcConnection::disposing() ::osl::MutexGuard aGuard(m_aMutex); m_nDocCount = 0; - m_pCloseListener.reset(); // dispose m_xDoc + if (m_xCloseVetoButTerminateListener.is()) + { + m_xCloseVetoButTerminateListener->stop(); // dispose m_xDoc + m_xCloseVetoButTerminateListener.clear(); + } m_xDoc.clear(); OConnection::disposing(); diff --git a/connectivity/source/inc/calc/CConnection.hxx b/connectivity/source/inc/calc/CConnection.hxx index 63b1d4ab084d..a5e46b237b26 100644 --- a/connectivity/source/inc/calc/CConnection.hxx +++ b/connectivity/source/inc/calc/CConnection.hxx @@ -21,7 +21,10 @@ #define INCLUDED_CONNECTIVITY_SOURCE_INC_CALC_CCONNECTION_HXX #include "file/FConnection.hxx" +#include <com/sun/star/frame/XDesktop2.hpp> +#include <com/sun/star/frame/XTerminateListener.hpp> #include <com/sun/star/uno/DeploymentException.hpp> +#include <unotools/closeveto.hxx> namespace com { namespace sun { namespace star { namespace sheet { class XSpreadsheetDocument; } @@ -39,12 +42,71 @@ namespace connectivity { // the spreadsheet document: css::uno::Reference< css::sheet::XSpreadsheetDocument > m_xDoc; - /// close listener that vetoes so nobody disposes m_xDoc - ::std::unique_ptr< ::utl::CloseVeto> m_pCloseListener; OUString m_sPassword; OUString m_aFileName; oslInterlockedCount m_nDocCount; + class CloseVetoButTerminateListener : public cppu::WeakComponentImplHelper<css::frame::XTerminateListener> + { + private: + /// close listener that vetoes so nobody else disposes m_xDoc + std::unique_ptr<utl::CloseVeto> m_pCloseListener; + /// but also listen to XDesktop and if app is terminating anyway, dispose m_xDoc while + /// its still possible to do so properly + css::uno::Reference<css::frame::XDesktop2> m_xDesktop; + osl::Mutex m_aMutex; + public: + CloseVetoButTerminateListener() + : cppu::WeakComponentImplHelper<css::frame::XTerminateListener>(m_aMutex) + { + } + + void start(const css::uno::Reference<css::uno::XInterface>& rCloseable, + const css::uno::Reference<css::frame::XDesktop2>& rDesktop) + { + m_xDesktop = rDesktop; + m_xDesktop->addTerminateListener(this); + m_pCloseListener.reset(new utl::CloseVeto(rCloseable, true)); + } + + void stop() + { + m_pCloseListener.reset(); + if (!m_xDesktop.is()) + return; + m_xDesktop->removeTerminateListener(this); + m_xDesktop.clear(); + } + + // XTerminateListener + virtual void SAL_CALL queryTermination(const css::lang::EventObject& /*rEvent*/) + throw(css::frame::TerminationVetoException, css::uno::RuntimeException, std::exception) override + { + } + + virtual void SAL_CALL notifyTermination(const css::lang::EventObject& /*rEvent*/) + throw(css::uno::RuntimeException, std::exception) override + { + stop(); + } + + virtual void SAL_CALL disposing() override + { + stop(); + cppu::WeakComponentImplHelperBase::disposing(); + } + + virtual void SAL_CALL disposing(const css::lang::EventObject& rEvent) + throw(css::uno::RuntimeException, std::exception) override + { + const bool bShutDown = (rEvent.Source == m_xDesktop); + if (bShutDown) + stop(); + } + }; + + rtl::Reference<CloseVetoButTerminateListener> m_xCloseVetoButTerminateListener; + public: OCalcConnection(ODriver* _pDriver); virtual ~OCalcConnection(); @@ -84,7 +146,7 @@ namespace connectivity } ~ODocHolder() { - m_xDoc.clear(); + m_xDoc.clear(); m_pConnection->releaseDoc(); } const css::uno::Reference< css::sheet::XSpreadsheetDocument>& getDoc() const { return m_xDoc; } |