[Libreoffice-commits] .: 2 commits - framework/inc framework/source

Caolán McNamara caolan at kemper.freedesktop.org
Fri Jan 21 03:17:25 PST 2011


 framework/inc/helper/mischelper.hxx                           |   71 ++++++++++
 framework/inc/uifactory/factoryconfiguration.hxx              |    1 
 framework/inc/uifactory/uielementfactorymanager.hxx           |    1 
 framework/source/uiconfiguration/imagemanagerimpl.cxx         |    6 
 framework/source/uiconfiguration/uicategorydescription.cxx    |   10 +
 framework/source/uiconfiguration/windowstateconfiguration.cxx |   10 +
 framework/source/uielement/uicommanddescription.cxx           |   21 ++
 framework/source/uifactory/factoryconfiguration.cxx           |    9 -
 framework/source/uifactory/uielementfactorymanager.cxx        |   10 +
 9 files changed, 125 insertions(+), 14 deletions(-)

New commits:
commit dbe02986e8005fd5e66f5b95fe6ba08253e6410d
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Fri Jan 21 10:51:30 2011 +0000

    break ownership cycle

diff --git a/framework/inc/helper/mischelper.hxx b/framework/inc/helper/mischelper.hxx
index ceedf78..e142893 100644
--- a/framework/inc/helper/mischelper.hxx
+++ b/framework/inc/helper/mischelper.hxx
@@ -31,8 +31,11 @@
 
 #include <com/sun/star/linguistic2/XLanguageGuessing.hpp>
 #include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XContainerListener.hpp>
 #include <com/sun/star/frame/XFrame.hpp>
 
+#include <cppuhelper/implbase1.hxx>
+
 #include <i18npool/lang.h>
 #include <svl/languageoptions.hxx>
 #include <rtl/ustring.hxx>
@@ -119,6 +122,74 @@ void FillLangItems( std::set< ::rtl::OUString > &rLangItems,
         const ::rtl::OUString & rKeyboardLang,
         const ::rtl::OUString & rGuessedTextLang );
 
+//It's common for an object to want to create and own a Broadcaster and set
+//itself as a Listener on its own Broadcaster member.
+//
+//However, calling addListener on a Broadcaster means that the Broadcaster adds
+//a reference to the Listener leading to an ownership cycle where the Listener
+//owns the Broadcaster which "owns" the Listener.
+//
+//The WeakContainerListener allows breaking this cycle and retrofitting
+//afflicted implentations fairly easily.
+//
+//OriginalListener owns the Broadcaster which "owns" the WeakContainerListener
+//which forwards the events to the OriginalListener without taking ownership of
+//it.
+class WeakContainerListener : public ::cppu::WeakImplHelper1<com::sun::star::container::XContainerListener>
+{
+    private:
+        com::sun::star::uno::WeakReference<com::sun::star::container::XContainerListener> mxOwner;
+
+    public:
+        WeakContainerListener(com::sun::star::uno::Reference<com::sun::star::container::XContainerListener> xOwner)
+            : mxOwner(xOwner)
+        {
+        }
+
+        virtual ~WeakContainerListener()
+        {
+        }
+
+        // container.XContainerListener
+        virtual void SAL_CALL elementInserted(const com::sun::star::container::ContainerEvent& rEvent)
+            throw(com::sun::star::uno::RuntimeException)
+        {
+            com::sun::star::uno::Reference<com::sun::star::container::XContainerListener> xOwner(mxOwner.get(),
+                com::sun::star::uno::UNO_QUERY);
+            if (xOwner.is())
+                xOwner->elementInserted(rEvent);
+        }
+
+        virtual void SAL_CALL elementRemoved(const com::sun::star::container::ContainerEvent& rEvent)
+            throw(com::sun::star::uno::RuntimeException)
+        {
+            com::sun::star::uno::Reference<com::sun::star::container::XContainerListener> xOwner(mxOwner.get(),
+                com::sun::star::uno::UNO_QUERY);
+            if (xOwner.is())
+                xOwner->elementRemoved(rEvent);
+        }
+
+        virtual void SAL_CALL elementReplaced(const com::sun::star::container::ContainerEvent& rEvent)
+            throw(com::sun::star::uno::RuntimeException)
+        {
+            com::sun::star::uno::Reference<com::sun::star::container::XContainerListener> xOwner(mxOwner.get(),
+                com::sun::star::uno::UNO_QUERY);
+            if (xOwner.is())
+                xOwner->elementReplaced(rEvent);
+        }
+
+        // lang.XEventListener
+        virtual void SAL_CALL disposing(const com::sun::star::lang::EventObject& rEvent)
+            throw(com::sun::star::uno::RuntimeException)
+        {
+            com::sun::star::uno::Reference<com::sun::star::container::XContainerListener> xOwner(mxOwner.get(),
+                com::sun::star::uno::UNO_QUERY);
+            if (xOwner.is())
+                xOwner->disposing(rEvent);
+
+        }
+};
+
 } // namespace framework
 
 #endif // __MISC_HELPER_HXX_
diff --git a/framework/inc/uifactory/factoryconfiguration.hxx b/framework/inc/uifactory/factoryconfiguration.hxx
index 0ced586..4030155 100644
--- a/framework/inc/uifactory/factoryconfiguration.hxx
+++ b/framework/inc/uifactory/factoryconfiguration.hxx
@@ -117,6 +117,7 @@ private:
     ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >    m_xServiceManager;
     ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >    m_xConfigProvider;
     ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >        m_xConfigAccess;
+    ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener > m_xConfigAccessListener;
     sal_Bool                          m_bConfigAccessInitialized;
     bool                              m_bAskValue;
 };
diff --git a/framework/inc/uifactory/uielementfactorymanager.hxx b/framework/inc/uifactory/uielementfactorymanager.hxx
index 80b2711..55eeda6 100644
--- a/framework/inc/uifactory/uielementfactorymanager.hxx
+++ b/framework/inc/uifactory/uielementfactorymanager.hxx
@@ -113,6 +113,7 @@ namespace framework
         ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xServiceManager;
         ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xConfigProvider;
         ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >     m_xConfigAccess;
+        ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener > m_xConfigListener;
         sal_Bool                          m_bConfigAccessInitialized;
         bool							  m_bConfigDirty;
 };
diff --git a/framework/source/uiconfiguration/uicategorydescription.cxx b/framework/source/uiconfiguration/uicategorydescription.cxx
index fddea76..1bc66fc 100644
--- a/framework/source/uiconfiguration/uicategorydescription.cxx
+++ b/framework/source/uiconfiguration/uicategorydescription.cxx
@@ -39,6 +39,8 @@
 
 #include "properties.h"
 
+#include "helper/mischelper.hxx"
+
 //_________________________________________________________________________________________________________________
 //	interface includes
 //_________________________________________________________________________________________________________________
@@ -148,6 +150,7 @@ class ConfigurationAccess_UICategory : // Order is neccessary for right initiali
         Reference< XMultiServiceFactory > m_xServiceManager;
         Reference< XMultiServiceFactory > m_xConfigProvider;
         Reference< XNameAccess >          m_xConfigAccess;
+        Reference< XContainerListener >   m_xConfigListener;
         sal_Bool                          m_bConfigAccessInitialized;
         sal_Bool                          m_bCacheFilled;
         IdToInfoCache                     m_aIdCache;
@@ -180,7 +183,7 @@ ConfigurationAccess_UICategory::~ConfigurationAccess_UICategory()
     ResetableGuard aLock( m_aLock );
     Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
     if ( xContainer.is() )
-        xContainer->removeContainerListener( this );
+        xContainer->removeContainerListener(m_xConfigListener);
 }
 
 // XNameAccess
@@ -387,7 +390,10 @@ sal_Bool ConfigurationAccess_UICategory::initializeConfigAccess()
             // Add as container listener
             Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
             if ( xContainer.is() )
-                xContainer->addContainerListener( this );
+            {
+                m_xConfigListener = new WeakContainerListener(this);
+                xContainer->addContainerListener(m_xConfigListener);
+            }
         }
 
         return sal_True;
diff --git a/framework/source/uiconfiguration/windowstateconfiguration.cxx b/framework/source/uiconfiguration/windowstateconfiguration.cxx
index e4f2de7..600e9cf 100644
--- a/framework/source/uiconfiguration/windowstateconfiguration.cxx
+++ b/framework/source/uiconfiguration/windowstateconfiguration.cxx
@@ -36,6 +36,8 @@
 #include <threadhelp/resetableguard.hxx>
 #include "services.h"
 
+#include "helper/mischelper.hxx"
+
 //_________________________________________________________________________________________________________________
 //	interface includes
 //_________________________________________________________________________________________________________________
@@ -264,6 +266,7 @@ class ConfigurationAccess_WindowState : // interfaces
         Reference< XMultiServiceFactory > m_xServiceManager;
         Reference< XMultiServiceFactory > m_xConfigProvider;
         Reference< XNameAccess >          m_xConfigAccess;
+        Reference< XContainerListener >   m_xConfigListener;
         ResourceURLToInfoCache            m_aResourceURLToInfoCache;
         sal_Bool                          m_bConfigAccessInitialized : 1,
                                           m_bModified : 1;
@@ -321,7 +324,7 @@ ConfigurationAccess_WindowState::~ConfigurationAccess_WindowState()
     ResetableGuard aLock( m_aLock );
     Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
     if ( xContainer.is() )
-        xContainer->removeContainerListener( this );
+        xContainer->removeContainerListener(m_xConfigListener);
 }
 
 // XNameAccess
@@ -1324,7 +1327,10 @@ sal_Bool ConfigurationAccess_WindowState::impl_initializeConfigAccess()
             // Add as container listener
             Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
             if ( xContainer.is() )
-                xContainer->addContainerListener( this );
+            {
+                m_xConfigListener = new WeakContainerListener(this);
+                xContainer->addContainerListener(m_xConfigListener);
+            }
         }
 
         return sal_True;
diff --git a/framework/source/uielement/uicommanddescription.cxx b/framework/source/uielement/uicommanddescription.cxx
index c9c7956..8a9ec11 100644
--- a/framework/source/uielement/uicommanddescription.cxx
+++ b/framework/source/uielement/uicommanddescription.cxx
@@ -38,6 +38,8 @@
 
 #include "properties.h"
 
+#include "helper/mischelper.hxx"
+
 //_________________________________________________________________________________________________________________
 //	interface includes
 //_________________________________________________________________________________________________________________
@@ -193,9 +195,10 @@ class ConfigurationAccess_UICommand : // Order is neccessary for right initializ
         Reference< XNameAccess >          m_xGenericUICommands;
         Reference< XMultiServiceFactory > m_xServiceManager;
         Reference< XMultiServiceFactory > m_xConfigProvider;
-        //Reference< XMultiServiceFactory > m_xConfigProviderPopups;
         Reference< XNameAccess >          m_xConfigAccess;
+        Reference< XContainerListener >   m_xConfigListener;
         Reference< XNameAccess >          m_xConfigAccessPopups;
+        Reference< XContainerListener >   m_xConfigAccessListener;
         Sequence< rtl::OUString >         m_aCommandImageList;
         Sequence< rtl::OUString >         m_aCommandRotateImageList;
         Sequence< rtl::OUString >         m_aCommandMirrorImageList;
@@ -246,10 +249,10 @@ ConfigurationAccess_UICommand::~ConfigurationAccess_UICommand()
     ResetableGuard aLock( m_aLock );
     Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
     if ( xContainer.is() )
-        xContainer->removeContainerListener( this );
+        xContainer->removeContainerListener(m_xConfigListener);
     xContainer = Reference< XContainer >( m_xConfigAccessPopups, UNO_QUERY );
     if ( xContainer.is() )
-        xContainer->removeContainerListener( this );
+        xContainer->removeContainerListener(m_xConfigAccessListener);
 }
 
 // XNameAccess
@@ -394,7 +397,7 @@ void ConfigurationAccess_UICommand::impl_fill(const Reference< XNameAccess >& _x
             {
             }
         }
-    } // if ( m_xConfigAccessPopups.is() )
+    }
 }
 sal_Bool ConfigurationAccess_UICommand::fillCache()
 {
@@ -558,7 +561,10 @@ sal_Bool ConfigurationAccess_UICommand::initializeConfigAccess()
             // Add as container listener
             Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
             if ( xContainer.is() )
-                xContainer->addContainerListener( this );
+            {
+                m_xConfigListener = new WeakContainerListener(this);
+                xContainer->addContainerListener(m_xConfigListener);
+            }
         }
 
         aPropValue.Value <<= m_aConfigPopupAccess;
@@ -569,7 +575,10 @@ sal_Bool ConfigurationAccess_UICommand::initializeConfigAccess()
             // Add as container listener
             Reference< XContainer > xContainer( m_xConfigAccessPopups, UNO_QUERY );
             if ( xContainer.is() )
-                xContainer->addContainerListener( this );
+            {
+                m_xConfigAccessListener = new WeakContainerListener(this);
+                xContainer->addContainerListener(m_xConfigAccessListener);
+            }
         }
 
         return sal_True;
diff --git a/framework/source/uifactory/factoryconfiguration.cxx b/framework/source/uifactory/factoryconfiguration.cxx
index 3c253ee..2f96a26 100644
--- a/framework/source/uifactory/factoryconfiguration.cxx
+++ b/framework/source/uifactory/factoryconfiguration.cxx
@@ -36,6 +36,8 @@
 #include <threadhelp/resetableguard.hxx>
 #include "services.h"
 
+#include "helper/mischelper.hxx"
+
 //_________________________________________________________________________________________________________________
 //	interface includes
 //_________________________________________________________________________________________________________________
@@ -103,7 +105,7 @@ ConfigurationAccess_ControllerFactory::~ConfigurationAccess_ControllerFactory()
     
     Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
     if ( xContainer.is() )
-        xContainer->removeContainerListener( this );
+        xContainer->removeContainerListener(m_xConfigAccessListener);
 }
 
 rtl::OUString ConfigurationAccess_ControllerFactory::getServiceFromCommandModule( const rtl::OUString& rCommandURL, const rtl::OUString& rModule ) const
@@ -269,7 +271,10 @@ void ConfigurationAccess_ControllerFactory::readConfigurationData()
         aLock.unlock();
 
         if ( xContainer.is() )
-            xContainer->addContainerListener( this );
+        {
+            m_xConfigAccessListener = new WeakContainerListener(this);
+            xContainer->addContainerListener(m_xConfigAccessListener);
+        }
     }
 }
 
diff --git a/framework/source/uifactory/uielementfactorymanager.cxx b/framework/source/uifactory/uielementfactorymanager.cxx
index 9ca88c3..ed3889d 100644
--- a/framework/source/uifactory/uielementfactorymanager.cxx
+++ b/framework/source/uifactory/uielementfactorymanager.cxx
@@ -37,6 +37,8 @@
 #include <threadhelp/resetableguard.hxx>
 #include "services.h"
 
+#include "helper/mischelper.hxx"
+
 //_________________________________________________________________________________________________________________
 //	interface includes
 //_________________________________________________________________________________________________________________
@@ -55,6 +57,7 @@
 #include <tools/urlobj.hxx>
 #include <vcl/svapp.hxx>
 #include <rtl/logfile.hxx>
+
 //_________________________________________________________________________________________________________________
 //	Defines
 //_________________________________________________________________________________________________________________
@@ -115,7 +118,7 @@ ConfigurationAccess_FactoryManager::~ConfigurationAccess_FactoryManager()
     
     Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
     if ( xContainer.is() )
-        xContainer->removeContainerListener( this );
+        xContainer->removeContainerListener(m_xConfigListener);
 }
 
 rtl::OUString ConfigurationAccess_FactoryManager::getFactorySpecifierFromTypeNameModule( const rtl::OUString& rType, const rtl::OUString& rName, const rtl::OUString& rModule ) const
@@ -353,7 +356,10 @@ void ConfigurationAccess_FactoryManager::readConfigurationData()
         aLock.unlock();
         // UNSAFE
         if ( xContainer.is() )
-            xContainer->addContainerListener( this );
+        {
+            m_xConfigListener = new WeakContainerListener(this); 
+            xContainer->addContainerListener(m_xConfigListener);
+        }
     }
 }
 
commit 87ce4f4744188cd3a76315896bcf2ab03c4378f4
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Fri Jan 21 10:50:49 2011 +0000

    break cycle and clear owner reference on dispose

diff --git a/framework/source/uiconfiguration/imagemanagerimpl.cxx b/framework/source/uiconfiguration/imagemanagerimpl.cxx
index 029165d..bca1f2d 100644
--- a/framework/source/uiconfiguration/imagemanagerimpl.cxx
+++ b/framework/source/uiconfiguration/imagemanagerimpl.cxx
@@ -752,6 +752,8 @@ void ImageManagerImpl::dispose()
         }
         delete m_pDefaultImageList;
         m_pDefaultImageList = 0;
+
+        m_xOwner.clear();
     }
     
 }
@@ -1455,6 +1457,10 @@ void ImageManagerImpl::implts_notifyContainerListener( const ConfigurationEvent&
 void ImageManagerImpl::clear()
 {
     ResetableGuard aGuard( m_aLock );
+
+    if (!m_pUserImageList)
+        return;
+
     for ( sal_Int32 n = 0; n < ImageType_COUNT; n++ )
     {
         delete m_pUserImageList[n];


More information about the Libreoffice-commits mailing list