summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoel Grandin <noel@peralex.com>2014-09-30 16:13:47 +0200
committerStephan Bergmann <sbergman@redhat.com>2014-10-02 13:00:08 +0200
commitd8be5a55760b01efa32708411c6e47fe74600edc (patch)
tree6edf19752904f90dd348d3cbb9a16d6391b58b60
parent18ceb207ddd8e9065a8e0bd4a64163a3a2a0a0ce (diff)
optimise UNO Sequence destructor
to avoid expensive function calls until the refcount reaches 0 Signed-off-by: Stephan Bergmann <sbergman@redhat.com>, slightly changing it to add a uno_type_sequence_destroy to uno/sequence2.h instead of a uno_type_destructSequence to uno/data.h. Change-Id: I3bbff3294f2b515fc3c68c4c6c1cb16829f5cc44
-rw-r--r--cppu/source/uno/destr.hxx55
-rw-r--r--cppu/source/uno/sequence.cxx8
-rw-r--r--cppu/util/cppu.map5
-rw-r--r--include/com/sun/star/uno/Sequence.hxx9
-rw-r--r--include/uno/sequence2.h14
5 files changed, 67 insertions, 24 deletions
diff --git a/cppu/source/uno/destr.hxx b/cppu/source/uno/destr.hxx
index 9cce1c692c5d..95f496e10c56 100644
--- a/cppu/source/uno/destr.hxx
+++ b/cppu/source/uno/destr.hxx
@@ -19,6 +19,10 @@
#ifndef INCLUDED_CPPU_SOURCE_UNO_DESTR_HXX
#define INCLUDED_CPPU_SOURCE_UNO_DESTR_HXX
+#include <sal/config.h>
+
+#include <cassert>
+
#include "prim.hxx"
@@ -255,38 +259,47 @@ inline sal_Int32 idestructElements(
}
}
-
-inline void idestructSequence(
+inline void idestroySequence(
uno_Sequence * pSeq,
typelib_TypeDescriptionReference * pType,
typelib_TypeDescription * pTypeDescr,
uno_ReleaseFunc release )
{
- if (osl_atomic_decrement( &pSeq->nRefCount ) == 0)
+ assert(pSeq != nullptr);
+ assert(pSeq->nRefCount == 0);
+ if (pSeq->nElements > 0)
{
- if (pSeq->nElements > 0)
+ if (pTypeDescr)
{
- if (pTypeDescr)
- {
- idestructElements(
- pSeq->elements,
- ((typelib_IndirectTypeDescription *) pTypeDescr)->pType, 0,
- pSeq->nElements, release );
- }
- else
- {
- TYPELIB_DANGER_GET( &pTypeDescr, pType );
- idestructElements(
- pSeq->elements,
- ((typelib_IndirectTypeDescription *) pTypeDescr)->pType, 0,
- pSeq->nElements, release );
- TYPELIB_DANGER_RELEASE( pTypeDescr );
- }
+ idestructElements(
+ pSeq->elements,
+ ((typelib_IndirectTypeDescription *) pTypeDescr)->pType, 0,
+ pSeq->nElements, release );
+ }
+ else
+ {
+ TYPELIB_DANGER_GET( &pTypeDescr, pType );
+ idestructElements(
+ pSeq->elements,
+ ((typelib_IndirectTypeDescription *) pTypeDescr)->pType, 0,
+ pSeq->nElements, release );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
}
- ::rtl_freeMemory( pSeq );
}
+ ::rtl_freeMemory( pSeq );
}
+inline void idestructSequence(
+ uno_Sequence * pSeq,
+ typelib_TypeDescriptionReference * pType,
+ typelib_TypeDescription * pTypeDescr,
+ uno_ReleaseFunc release )
+{
+ if (osl_atomic_decrement( &pSeq->nRefCount ) == 0)
+ {
+ idestroySequence(pSeq, pType, pTypeDescr, release);
+ }
+}
inline void _destructData(
void * pValue,
diff --git a/cppu/source/uno/sequence.cxx b/cppu/source/uno/sequence.cxx
index cbd4369fa385..9523a6859ff4 100644
--- a/cppu/source/uno/sequence.cxx
+++ b/cppu/source/uno/sequence.cxx
@@ -920,6 +920,14 @@ void SAL_CALL uno_type_sequence_assign(
}
}
+void uno_type_sequence_destroy(
+ uno_Sequence * sequence, typelib_TypeDescriptionReference * type,
+ uno_ReleaseFunc release)
+ SAL_THROW_EXTERN_C()
+{
+ idestroySequence(sequence, type, nullptr, release);
+}
+
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cppu/util/cppu.map b/cppu/util/cppu.map
index 6c8095bd0d6f..df724a5c96f0 100644
--- a/cppu/util/cppu.map
+++ b/cppu/util/cppu.map
@@ -145,6 +145,11 @@ UDK_3.3 { # OOo 2.4
cppu_unsatisfied_iset_msg;
} UDK_3.2;
+LIBO_UDK_4.4 { # symbols available in >= LibO 4.4
+ global:
+ uno_type_sequence_destroy;
+} UDK_3.3;
+
# Unique libstdc++ symbols:
GLIBCXX_3.4 {
global:
diff --git a/include/com/sun/star/uno/Sequence.hxx b/include/com/sun/star/uno/Sequence.hxx
index ba3b8c123322..1ee59aebac45 100644
--- a/include/com/sun/star/uno/Sequence.hxx
+++ b/include/com/sun/star/uno/Sequence.hxx
@@ -95,9 +95,12 @@ inline Sequence< E >::Sequence( sal_Int32 len )
template< class E >
inline Sequence< E >::~Sequence()
{
- const Type & rType = ::cppu::getTypeFavourUnsigned( this );
- ::uno_type_destructData(
- this, rType.getTypeLibType(), (uno_ReleaseFunc)cpp_release );
+ if (osl_atomic_decrement( &_pSequence->nRefCount ) == 0)
+ {
+ const Type & rType = ::cppu::getTypeFavourUnsigned( this );
+ uno_type_sequence_destroy(
+ _pSequence, rType.getTypeLibType(), (uno_ReleaseFunc)cpp_release );
+ }
}
template< class E >
diff --git a/include/uno/sequence2.h b/include/uno/sequence2.h
index 42208f0f8bab..3b55ba007cf1 100644
--- a/include/uno/sequence2.h
+++ b/include/uno/sequence2.h
@@ -172,6 +172,20 @@ CPPU_DLLPUBLIC sal_Bool SAL_CALL uno_type_sequence_realloc(
uno_ReleaseFunc release )
SAL_THROW_EXTERN_C();
+/** Destroy a sequence whose reference count has dropped to zero.
+
+ @param sequence must be non-null, sequence->nRefCount must be zero
+ @param type the type of the sequence, must be non-null
+ @param release function called each time an interface needs to be release,
+ must be non-null
+
+ @since LibreOffice 4.4
+*/
+CPPU_DLLPUBLIC void SAL_CALL uno_type_sequence_destroy(
+ uno_Sequence * sequence, struct _typelib_TypeDescriptionReference * type,
+ uno_ReleaseFunc release)
+ SAL_THROW_EXTERN_C();
+
#ifdef __cplusplus
}
#endif