From 6c419129f27d61295508d14448351f62e994806b Mon Sep 17 00:00:00 2001 From: Noel Grandin Date: Tue, 24 May 2016 15:10:36 +0200 Subject: optimise references list handling in OWeakConnectionPoint some more After my commit 1e063e8b "optimise references list handling in OWeakConnectionPoint" Reduce scope of locking, and copy a the performance trick from OInterfaceContainerHelper. Change-Id: Idc218e9d4edf45f8c37c7e517d1a26821800448b Reviewed-on: https://gerrit.libreoffice.org/25406 Tested-by: Jenkins Reviewed-by: Michael Stahl --- 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 14334259ee8c..b6abef5ebe56 100644 --- a/cppuhelper/source/weak.cxx +++ b/cppuhelper/source/weak.cxx @@ -107,12 +107,14 @@ void SAL_CALL OWeakConnectionPoint::release() throw() void SAL_CALL OWeakConnectionPoint::dispose() throw(css::uno::RuntimeException) { - MutexGuard aGuard(getWeakMutex()); - Any ex; - // 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); + { // only hold the mutex while we access the field + MutexGuard aGuard(getWeakMutex()); + // 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 + aCopy.swap(m_aReferences); + } + Any ex; for (const Reference & i : aCopy ) { try @@ -172,8 +174,16 @@ void SAL_CALL OWeakConnectionPoint::removeReference(const Reference< XReference throw(css::uno::RuntimeException, std::exception) { 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 + // Search from end because the thing that last added a ref is most likely to be the + // first to remove a ref. + // It's not really valid to compare the pointer directly, but it's faster. + for (auto it = m_aReferences.rbegin(); it != m_aReferences.rend(); ++it) { + if (it->get() == rRef.get()) { + m_aReferences.erase( it.base()-1 ); + return; + } + } + // interface not found, use the correct compare method auto it = std::find(m_aReferences.rbegin(), m_aReferences.rend(), rRef); if ( it != m_aReferences.rend() ) m_aReferences.erase( it.base()-1 ); -- cgit