[Libreoffice-commits] core.git: connectivity/source

Caolán McNamara caolanm at redhat.com
Sun Aug 28 10:01:34 UTC 2016


 connectivity/source/drivers/calc/CConnection.cxx |   16 ++++-
 connectivity/source/inc/calc/CConnection.hxx     |   68 +++++++++++++++++++++--
 2 files changed, 77 insertions(+), 7 deletions(-)

New commits:
commit 45e01be11111213f689ba5f1fa319e3dc48ea9c5
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Sat Aug 27 21:32:39 2016 +0100

    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 at libreoffice.org>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/connectivity/source/drivers/calc/CConnection.cxx b/connectivity/source/drivers/calc/CConnection.cxx
index 3934fd4..a315bc6 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 63b1d4a..a5e46b2 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; }


More information about the Libreoffice-commits mailing list