[Libreoffice-commits] core.git: 2 commits - external/boost unoxml/source

Caolán McNamara caolanm at redhat.com
Thu Jul 17 03:54:32 PDT 2014


 external/boost/UnpackedTarball_boost.mk                 |    1 
 external/boost/boost.date_time.Wshadow.warnings.patch.1 |  117 ++++++++++++++++
 unoxml/source/dom/elementlist.cxx                       |   65 +++++++-
 unoxml/source/dom/elementlist.hxx                       |   50 ++++++
 4 files changed, 222 insertions(+), 11 deletions(-)

New commits:
commit a4928075958fd911d751a74b3a06e6730b557272
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Thu Jul 17 10:29:36 2014 +0100

    fix memleak circular dependency of CElementList and CElement
    
    launching impress leaks 70+k
    
    ==1458== 78,741 (152 direct, 78,589 indirect) bytes in 1 blocks are definitely lost in loss record 24,296 of 24,315
    ==1458==    at 0x4A0645D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==1458==    by 0x4C3895D: rtl_allocateMemory_SYSTEM(unsigned long) (alloc_global.cxx:270)
    ==1458==    by 0x4C38A64: rtl_allocateMemory (alloc_global.cxx:303)
    ==1458==    by 0x2DCC0B67: cppu::OWeakObject::operator new(unsigned long) (weak.hxx:85)
    ==1458==    by 0x2DCCB3D3: DOM::CDocument::getElementsByTagName(rtl::OUString const&) (document.cxx:714)
    ==1458==    by 0x25DC99D6: SdDrawDocument::InitLayoutVector() (drawdoc.cxx:1008)
    
    because the CElementList owns the CElement via m_pElement and
    m_pElement owns the CElementList via the addEventListener.
    
    Use a WeakEventListener pattern to let the CElement own
    that helper which itself doesn't own the CElementList but is
    owned by it instead, and forwards the events to the CElementList
    
    In order to use that pattern the CElementList must be have a m_refCount
    of 1 when the addEventListener is called, i.e. post ctor, so rename
    the original CElementList as CElementListImpl and call its registerListener
    from a wrapper CElementList
    
    Change-Id: Ibd4f19b619543a4ef580366c69efb61b526696ab

diff --git a/unoxml/source/dom/elementlist.cxx b/unoxml/source/dom/elementlist.cxx
index 98d150b..9230917 100644
--- a/unoxml/source/dom/elementlist.cxx
+++ b/unoxml/source/dom/elementlist.cxx
@@ -28,6 +28,34 @@ using namespace css::uno;
 using namespace css::xml::dom;
 using namespace css::xml::dom::events;
 
+namespace
+{
+    class WeakEventListener : public ::cppu::WeakImplHelper1<css::xml::dom::events::XEventListener>
+    {
+    private:
+        css::uno::WeakReference<css::xml::dom::events::XEventListener> mxOwner;
+
+    public:
+        WeakEventListener(const css::uno::Reference<css::xml::dom::events::XEventListener>& rOwner)
+            : mxOwner(rOwner)
+        {
+        }
+
+        virtual ~WeakEventListener()
+        {
+        }
+
+        virtual void SAL_CALL handleEvent(const css::uno::Reference<css::xml::dom::events::XEvent>& rEvent)
+            throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE
+        {
+            css::uno::Reference<css::xml::dom::events::XEventListener> xOwner(mxOwner.get(),
+                css::uno::UNO_QUERY);
+            if (xOwner.is())
+                xOwner->handleEvent(rEvent);
+        }
+    };
+}
+
 namespace DOM
 {
 
@@ -43,25 +71,46 @@ namespace DOM
     CElementList::CElementList(::rtl::Reference<CElement> const& pElement,
             ::osl::Mutex & rMutex,
             OUString const& rName, OUString const*const pURI)
+        : m_xImpl(new CElementListImpl(pElement, rMutex, rName, pURI))
+    {
+        if (pElement.is()) {
+            m_xImpl->registerListener(*pElement);
+        }
+    }
+
+    CElementListImpl::CElementListImpl(::rtl::Reference<CElement> const& pElement,
+            ::osl::Mutex & rMutex,
+            OUString const& rName, OUString const*const pURI)
         : m_pElement(pElement)
         , m_rMutex(rMutex)
         , m_pName(lcl_initXmlString(rName))
         , m_pURI((pURI) ? lcl_initXmlString(*pURI) : 0)
         , m_bRebuild(true)
     {
-        if (m_pElement.is()) {
-            registerListener(*m_pElement);
+    }
+
+    CElementListImpl::~CElementListImpl()
+    {
+        if (m_xEventListener.is() && m_pElement.is())
+        {
+            Reference< XEventTarget > xTarget(static_cast<XElement*>(m_pElement.get()), UNO_QUERY);
+            assert(xTarget.is());
+            if (!xTarget.is())
+                return;
+            bool capture = false;
+            xTarget->removeEventListener("DOMSubtreeModified", m_xEventListener, capture);
         }
     }
 
-    void CElementList::registerListener(CElement & rElement)
+    void CElementListImpl::registerListener(CElement & rElement)
     {
         try {
             Reference< XEventTarget > const xTarget(
                     static_cast<XElement*>(& rElement), UNO_QUERY_THROW);
             bool capture = false;
+            m_xEventListener = new WeakEventListener(this);
             xTarget->addEventListener("DOMSubtreeModified",
-                    Reference< XEventListener >(this), capture);
+                    m_xEventListener, capture);
         } catch (const Exception &e){
             OString aMsg("Exception caught while registering NodeList as listener:\n");
             aMsg += OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
@@ -69,7 +118,7 @@ namespace DOM
         }
     }
 
-    void CElementList::buildlist(xmlNodePtr pNode, bool start)
+    void CElementListImpl::buildlist(xmlNodePtr pNode, bool start)
     {
         // bail out if no rebuild is needed
         if (start) {
@@ -107,7 +156,7 @@ namespace DOM
     /**
     The number of nodes in the list.
     */
-    sal_Int32 SAL_CALL CElementList::getLength() throw (RuntimeException, std::exception)
+    sal_Int32 SAL_CALL CElementListImpl::getLength() throw (RuntimeException, std::exception)
     {
         ::osl::MutexGuard const g(m_rMutex);
 
@@ -120,7 +169,7 @@ namespace DOM
     /**
     Returns the indexth item in the collection.
     */
-    Reference< XNode > SAL_CALL CElementList::item(sal_Int32 index)
+    Reference< XNode > SAL_CALL CElementListImpl::item(sal_Int32 index)
         throw (RuntimeException, std::exception)
     {
         if (index < 0) throw RuntimeException();
@@ -139,7 +188,7 @@ namespace DOM
     }
 
     // tree mutations can change the list
-    void SAL_CALL CElementList::handleEvent(Reference< XEvent > const&)
+    void SAL_CALL CElementListImpl::handleEvent(Reference< XEvent > const&)
         throw (RuntimeException, std::exception)
     {
         ::osl::MutexGuard const g(m_rMutex);
diff --git a/unoxml/source/dom/elementlist.hxx b/unoxml/source/dom/elementlist.hxx
index 3cde5bc..18289e6 100644
--- a/unoxml/source/dom/elementlist.hxx
+++ b/unoxml/source/dom/elementlist.hxx
@@ -36,6 +36,7 @@
 #include <com/sun/star/xml/dom/events/XEvent.hpp>
 #include <com/sun/star/xml/dom/events/XEventListener.hpp>
 
+#include <cppuhelper/implbase1.hxx>
 #include <cppuhelper/implbase2.hxx>
 
 namespace DOM
@@ -44,11 +45,16 @@ namespace DOM
 
     typedef std::vector< xmlNodePtr > nodevector_t;
 
-    class CElementList
+    class CElementListImpl
         : public cppu::WeakImplHelper2< css::xml::dom::XNodeList,
                 css::xml::dom::events::XEventListener >
     {
     private:
+        /** @short  proxy weak binding to forward Events to ourself without
+                    an ownership cycle
+          */
+        css::uno::Reference< css::xml::dom::events::XEventListener > m_xEventListener;
+
         ::rtl::Reference<CElement> const m_pElement;
         ::osl::Mutex & m_rMutex;
         ::boost::scoped_array<xmlChar> const m_pName;
@@ -57,13 +63,16 @@ namespace DOM
         nodevector_t m_nodevector;
 
         void buildlist(xmlNodePtr pNode, bool start=true);
-        void registerListener(CElement & rElement);
 
     public:
-        CElementList(::rtl::Reference<CElement> const& pElement,
+        CElementListImpl(::rtl::Reference<CElement> const& pElement,
                 ::osl::Mutex & rMutex,
                 OUString const& rName, OUString const*const pURI = 0);
 
+        void registerListener(CElement & rElement);
+
+        ~CElementListImpl();
+
         /**
         The number of nodes in the list.
         */
@@ -78,6 +87,41 @@ namespace DOM
         virtual void SAL_CALL handleEvent(const css::uno::Reference< css::xml::dom::events::XEvent >& evt)
             throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     };
+
+    class CElementList
+        : public cppu::WeakImplHelper2< css::xml::dom::XNodeList,
+                css::xml::dom::events::XEventListener >
+    {
+    private:
+        rtl::Reference<CElementListImpl> m_xImpl;
+    public:
+        CElementList(::rtl::Reference<CElement> const& pElement,
+                ::osl::Mutex & rMutex,
+                OUString const& rName, OUString const*const pURI = 0);
+
+        /**
+        The number of nodes in the list.
+        */
+        virtual sal_Int32 SAL_CALL getLength() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
+        {
+            return m_xImpl->getLength();
+        }
+        /**
+        Returns the indexth item in the collection.
+        */
+        virtual css::uno::Reference< css::xml::dom::XNode > SAL_CALL item(sal_Int32 index)
+            throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
+        {
+            return m_xImpl->item(index);
+        }
+
+        // XEventListener
+        virtual void SAL_CALL handleEvent(const css::uno::Reference< css::xml::dom::events::XEvent >& evt)
+            throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
+        {
+            m_xImpl->handleEvent(evt);
+        }
+    };
 }
 
 #endif
commit bcbd2d65f5c0dd3d84a2311aabe9c0ade17bf375
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Thu Jul 17 08:26:44 2014 +0100

    fix higher debug levels build
    
    Change-Id: If002fa0140174e43128469fc0af35edd0dfb7839

diff --git a/external/boost/UnpackedTarball_boost.mk b/external/boost/UnpackedTarball_boost.mk
index f22f453..23fb367 100644
--- a/external/boost/UnpackedTarball_boost.mk
+++ b/external/boost/UnpackedTarball_boost.mk
@@ -73,6 +73,7 @@ boost_patches += boost.spirit.Wshadow.warnings.patch
 boost_patches += boost.spirit.Wunused-local-typedefs.warnings.patch
 # to-do: submit upstream
 boost_patches += boost.spirit.Wunused-parameter.warnings.patch
+boost_patches += boost.date_time.Wshadow.warnings.patch.1
 # fixed upstream
 boost_patches += boost.unordered.Wshadow.warnings.patch
 # https://svn.boost.org/trac/boost/ticket/9902
diff --git a/external/boost/boost.date_time.Wshadow.warnings.patch.1 b/external/boost/boost.date_time.Wshadow.warnings.patch.1
new file mode 100644
index 0000000..4b7a911
--- /dev/null
+++ b/external/boost/boost.date_time.Wshadow.warnings.patch.1
@@ -0,0 +1,117 @@
+--- a/boost/date_time/time_facet.hpp
++++ b/boost/date_time/time_facet.hpp
+@@ -439,31 +439,31 @@
+                               time_dur_arg.get_rep().as_special());
+       }
+ 
+-      string_type format(m_time_duration_format);
++      string_type local_format(m_time_duration_format);
+       if (time_dur_arg.is_negative()) {
+         // replace %- with minus sign.  Should we use the numpunct facet?
+-        boost::algorithm::replace_all(format,
++        boost::algorithm::replace_all(local_format,
+                                       duration_sign_negative_only,
+                                       negative_sign);
+           // remove all the %+ in the string with '-'
+-        boost::algorithm::replace_all(format,
++        boost::algorithm::replace_all(local_format,
+                                       duration_sign_always,
+                                       negative_sign);
+       }
+       else { //duration is positive
+         // remove all the %- combos from the string
+-        boost::algorithm::erase_all(format, duration_sign_negative_only);
++        boost::algorithm::erase_all(local_format, duration_sign_negative_only);
+         // remove all the %+ in the string with '+'
+-        boost::algorithm::replace_all(format,
++        boost::algorithm::replace_all(local_format,
+                                       duration_sign_always,
+                                       positive_sign);
+       }
+ 
+       // %T and %R have to be replaced here since they are not standard
+-      boost::algorithm::replace_all(format,
++      boost::algorithm::replace_all(local_format,
+         boost::as_literal(formats_type::full_24_hour_time_format),
+         boost::as_literal(formats_type::full_24_hour_time_expanded_format));
+-      boost::algorithm::replace_all(format,
++      boost::algorithm::replace_all(local_format,
+         boost::as_literal(formats_type::short_24_hour_time_format),
+         boost::as_literal(formats_type::short_24_hour_time_expanded_format));
+ 
+@@ -476,22 +476,22 @@
+        * here ourself.
+        */
+       string_type hours_str;
+-      if (format.find(unrestricted_hours_format) != string_type::npos) {
++      if (local_format.find(unrestricted_hours_format) != string_type::npos) {
+         hours_str = hours_as_string(time_dur_arg);
+-        boost::algorithm::replace_all(format, unrestricted_hours_format, hours_str);
++        boost::algorithm::replace_all(local_format, unrestricted_hours_format, hours_str);
+       }
+       // We still have to process restricted hours format specifier. In order to
+       // support parseability of durations in ISO format (%H%M%S), we'll have to
+       // restrict the stringified hours length to 2 characters.
+-      if (format.find(hours_format) != string_type::npos) {
++      if (local_format.find(hours_format) != string_type::npos) {
+         if (hours_str.empty())
+           hours_str = hours_as_string(time_dur_arg);
+         BOOST_ASSERT(hours_str.length() <= 2);
+-        boost::algorithm::replace_all(format, hours_format, hours_str);
++        boost::algorithm::replace_all(local_format, hours_format, hours_str);
+       }
+ 
+       string_type frac_str;
+-      if (format.find(seconds_with_fractional_seconds_format) != string_type::npos) {
++      if (local_format.find(seconds_with_fractional_seconds_format) != string_type::npos) {
+         // replace %s with %S.nnn
+         frac_str =
+           fractional_seconds_as_string(time_dur_arg, false);
+@@ -500,21 +500,21 @@
+         string_type replace_string(seconds_format);
+         replace_string += sep;
+         replace_string += frac_str;
+-        boost::algorithm::replace_all(format,
++        boost::algorithm::replace_all(local_format,
+                                       seconds_with_fractional_seconds_format,
+                                       replace_string);
+       }
+-      if (format.find(fractional_seconds_format) != string_type::npos) {
++      if (local_format.find(fractional_seconds_format) != string_type::npos) {
+         // replace %f with nnnnnnn
+         if (!frac_str.size()) {
+           frac_str = fractional_seconds_as_string(time_dur_arg, false);
+         }
+-        boost::algorithm::replace_all(format,
++        boost::algorithm::replace_all(local_format,
+                                       fractional_seconds_format,
+                                       frac_str);
+       }
+ 
+-      if (format.find(fractional_seconds_or_none_format) != string_type::npos) {
++      if (local_format.find(fractional_seconds_or_none_format) != string_type::npos) {
+         // replace %F with nnnnnnn or nothing if fs == 0
+         frac_str =
+           fractional_seconds_as_string(time_dur_arg, true);
+@@ -523,18 +523,18 @@
+           string_type replace_string;
+           replace_string += sep;
+           replace_string += frac_str;
+-          boost::algorithm::replace_all(format,
++          boost::algorithm::replace_all(local_format,
+                                         fractional_seconds_or_none_format,
+                                         replace_string);
+         }
+         else {
+-          boost::algorithm::erase_all(format,
++          boost::algorithm::erase_all(local_format,
+                                       fractional_seconds_or_none_format);
+         }
+       }
+ 
+       return this->do_put_tm(next_arg, ios_arg, fill_arg,
+-                       to_tm(time_dur_arg), format);
++                       to_tm(time_dur_arg), local_format);
+     }
+ 
+     OutItrT put(OutItrT next, std::ios_base& ios_arg,


More information about the Libreoffice-commits mailing list