basctl/source/basicide/iderdll.cxx          |    2 -
 framework/inc/services/desktop.hxx          |    2 +
 framework/source/services/desktop.cxx       |   29 ++++++++++++++++++++
 include/comphelper/unique_disposing_ptr.hxx |   40 +++++++++++++++++++++++-----
 sw/source/uibase/app/swdll.cxx              |    2 -
 5 files changed, 66 insertions(+), 9 deletions(-)

New commits:
commit 2f0020ba056e2b523c487dc42b40f0e4b9f9a9b0
Author: Markus Mohrhard <[email protected]>
Date:   Mon Jan 9 05:58:00 2017 +0100

    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 <[email protected]>
    Tested-by: Jenkins <[email protected]>
    Reviewed-by: Markus Mohrhard <[email protected]>
    (cherry picked from commit ad915fafd54f9115faea7147f82d80a942af2d68)
    Reviewed-on: https://gerrit.libreoffice.org/32928
    Reviewed-by: Michael Meeks <[email protected]>
    Reviewed-by: Michael Stahl <[email protected]>

diff --git a/basctl/source/basicide/iderdll.cxx 
b/basctl/source/basicide/iderdll.cxx
index 19d5961..d155780 100644
--- a/basctl/source/basicide/iderdll.cxx
+++ b/basctl/source/basicide/iderdll.cxx
@@ -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)
     { }
 };
 
diff --git a/framework/inc/services/desktop.hxx 
b/framework/inc/services/desktop.hxx
index e8fd001..bd766e8 100644
--- a/framework/inc/services/desktop.hxx
+++ b/framework/inc/services/desktop.hxx
@@ -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
diff --git a/framework/source/services/desktop.cxx 
b/framework/source/services/desktop.cxx
index 3e5f3a0..18eecb3 100644
--- a/framework/source/services/desktop.cxx
+++ b/framework/source/services/desktop.cxx
@@ -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();
 
diff --git a/include/comphelper/unique_disposing_ptr.hxx 
b/include/comphelper/unique_disposing_ptr.hxx
index 0f120b1..64ff540 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 803c2b8..ed4d3fa 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)
         {
         }
     };
_______________________________________________
Libreoffice-commits mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to