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>
This commit is contained in:
parent
5bdea25f68
commit
45e01be111
@ -31,7 +31,6 @@
|
|||||||
#include "calc/CPreparedStatement.hxx"
|
#include "calc/CPreparedStatement.hxx"
|
||||||
#include "calc/CStatement.hxx"
|
#include "calc/CStatement.hxx"
|
||||||
#include <unotools/pathoptions.hxx>
|
#include <unotools/pathoptions.hxx>
|
||||||
#include <unotools/closeveto.hxx>
|
|
||||||
#include <connectivity/dbexception.hxx>
|
#include <connectivity/dbexception.hxx>
|
||||||
#include <cppuhelper/exc_hlp.hxx>
|
#include <cppuhelper/exc_hlp.hxx>
|
||||||
#include <comphelper/processfactory.hxx>
|
#include <comphelper/processfactory.hxx>
|
||||||
@ -164,7 +163,8 @@ Reference< XSpreadsheetDocument> const & OCalcConnection::acquireDoc()
|
|||||||
::dbtools::throwGenericSQLException( sError, *this, aErrorDetails );
|
::dbtools::throwGenericSQLException( sError, *this, aErrorDetails );
|
||||||
}
|
}
|
||||||
osl_atomic_increment(&m_nDocCount);
|
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;
|
return m_xDoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,7 +172,11 @@ void OCalcConnection::releaseDoc()
|
|||||||
{
|
{
|
||||||
if ( osl_atomic_decrement(&m_nDocCount) == 0 )
|
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();
|
m_xDoc.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -182,7 +186,11 @@ void OCalcConnection::disposing()
|
|||||||
::osl::MutexGuard aGuard(m_aMutex);
|
::osl::MutexGuard aGuard(m_aMutex);
|
||||||
|
|
||||||
m_nDocCount = 0;
|
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();
|
m_xDoc.clear();
|
||||||
|
|
||||||
OConnection::disposing();
|
OConnection::disposing();
|
||||||
|
@ -21,7 +21,10 @@
|
|||||||
#define INCLUDED_CONNECTIVITY_SOURCE_INC_CALC_CCONNECTION_HXX
|
#define INCLUDED_CONNECTIVITY_SOURCE_INC_CALC_CCONNECTION_HXX
|
||||||
|
|
||||||
#include "file/FConnection.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 <com/sun/star/uno/DeploymentException.hpp>
|
||||||
|
#include <unotools/closeveto.hxx>
|
||||||
|
|
||||||
namespace com { namespace sun { namespace star {
|
namespace com { namespace sun { namespace star {
|
||||||
namespace sheet { class XSpreadsheetDocument; }
|
namespace sheet { class XSpreadsheetDocument; }
|
||||||
@ -39,12 +42,71 @@ namespace connectivity
|
|||||||
{
|
{
|
||||||
// the spreadsheet document:
|
// the spreadsheet document:
|
||||||
css::uno::Reference< css::sheet::XSpreadsheetDocument > m_xDoc;
|
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_sPassword;
|
||||||
OUString m_aFileName;
|
OUString m_aFileName;
|
||||||
oslInterlockedCount m_nDocCount;
|
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:
|
public:
|
||||||
OCalcConnection(ODriver* _pDriver);
|
OCalcConnection(ODriver* _pDriver);
|
||||||
virtual ~OCalcConnection();
|
virtual ~OCalcConnection();
|
||||||
@ -84,7 +146,7 @@ namespace connectivity
|
|||||||
}
|
}
|
||||||
~ODocHolder()
|
~ODocHolder()
|
||||||
{
|
{
|
||||||
m_xDoc.clear();
|
m_xDoc.clear();
|
||||||
m_pConnection->releaseDoc();
|
m_pConnection->releaseDoc();
|
||||||
}
|
}
|
||||||
const css::uno::Reference< css::sheet::XSpreadsheetDocument>& getDoc() const { return m_xDoc; }
|
const css::uno::Reference< css::sheet::XSpreadsheetDocument>& getDoc() const { return m_xDoc; }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user