From 1e063e8b7ea070a5b6990b3d6740ecae05aea66d Mon Sep 17 00:00:00 2001 From: Noel Grandin Date: Fri, 13 May 2016 08:48:41 +0200 Subject: optimise references list handling in OWeakConnectionPoint avoid the expensive sequence copying and deleting in OInterfaceContainerHelper. Change-Id: I00867b8a25b27d2a0b0babdf41a082c014e0e07d Reviewed-on: https://gerrit.libreoffice.org/24949 Tested-by: Jenkins Reviewed-by: Noel Grandin --- cppuhelper/source/weak.cxx | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'cppuhelper') diff --git a/cppuhelper/source/weak.cxx b/cppuhelper/source/weak.cxx index aa940affa26d..d81a41b6cc0e 100644 --- a/cppuhelper/source/weak.cxx +++ b/cppuhelper/source/weak.cxx @@ -24,6 +24,7 @@ #include #include #include +#include using namespace osl; using namespace com::sun::star::uno; @@ -53,7 +54,6 @@ public: explicit OWeakConnectionPoint( OWeakObject* pObj ) : m_aRefCount( 0 ) , m_pObject(pObj) - , m_aReferences( getWeakMutex() ) {} // noncopyable @@ -81,7 +81,7 @@ private: /// The weak object OWeakObject* m_pObject; /// The container to hold the weak references - OInterfaceContainerHelper m_aReferences; + std::vector> m_aReferences; }; // XInterface @@ -107,13 +107,17 @@ void SAL_CALL OWeakConnectionPoint::release() throw() void SAL_CALL OWeakConnectionPoint::dispose() throw(css::uno::RuntimeException) { + MutexGuard aGuard(getWeakMutex()); Any ex; - OInterfaceIteratorHelper aIt( m_aReferences ); - while( aIt.hasMoreElements() ) + // other code is going to call removeReference while we are doing this, so we need a + // copy, but since we are disposing and going away, we can just take the original data + std::vector> aCopy; + aCopy.swap(m_aReferences); + for (const Reference & i : aCopy ) { try { - static_cast(aIt.next())->dispose(); + i->dispose(); } catch (css::lang::DisposedException &) {} catch (RuntimeException &) @@ -159,14 +163,20 @@ Reference< XInterface > SAL_CALL OWeakConnectionPoint::queryAdapted() throw(css: void SAL_CALL OWeakConnectionPoint::addReference(const Reference< XReference >& rRef) throw(css::uno::RuntimeException, std::exception) { - m_aReferences.addInterface( (const Reference< XInterface > &)rRef ); + MutexGuard aGuard(getWeakMutex()); + m_aReferences.push_back( rRef ); } // XInterface void SAL_CALL OWeakConnectionPoint::removeReference(const Reference< XReference >& rRef) throw(css::uno::RuntimeException, std::exception) { - m_aReferences.removeInterface( (const Reference< XInterface > &)rRef ); + MutexGuard aGuard(getWeakMutex()); + // search from end because the thing that last added a ref is most likely to be the + // first to remove a ref + auto it = std::find(m_aReferences.rbegin(), m_aReferences.rend(), rRef); + if ( it != m_aReferences.rend() ) + m_aReferences.erase( it.base()-1 ); } -- cgit