summaryrefslogtreecommitdiff
path: root/cppuhelper/source/weak.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'cppuhelper/source/weak.cxx')
-rw-r--r--cppuhelper/source/weak.cxx128
1 files changed, 79 insertions, 49 deletions
diff --git a/cppuhelper/source/weak.cxx b/cppuhelper/source/weak.cxx
index a11e52bbbb78..6bb353faa9bd 100644
--- a/cppuhelper/source/weak.cxx
+++ b/cppuhelper/source/weak.cxx
@@ -21,7 +21,6 @@
#include <sal/log.hxx>
#include <osl/diagnose.h>
-#include <osl/mutex.hxx>
#include <cppuhelper/weakagg.hxx>
#include <cppuhelper/exc_hlp.hxx>
#include <cppuhelper/queryinterface.hxx>
@@ -30,21 +29,16 @@
#include <algorithm>
#include <vector>
+#include <mutex>
-using namespace osl;
using namespace com::sun::star::uno;
-/** */ //for docpp
namespace cppu
{
// due to static Reflection destruction from usr, there must be a mutex leak (#73272#)
// this is used to lock all instances of OWeakConnectionPoint and OWeakRefListener as well as OWeakObject::m_pWeakConnectionPoint
-static Mutex & getWeakMutex()
-{
- static Mutex * s_pMutex = new Mutex();
- return *s_pMutex;
-}
+static std::mutex * gpWeakMutex = new std::mutex;
//-- OWeakConnectionPoint ----------------------------------------------------
@@ -66,8 +60,8 @@ public:
// XInterface
Any SAL_CALL queryInterface( const Type & rType ) override;
- void SAL_CALL acquire() throw() override;
- void SAL_CALL release() throw() override;
+ void SAL_CALL acquire() noexcept override;
+ void SAL_CALL release() noexcept override;
// XAdapter
css::uno::Reference< css::uno::XInterface > SAL_CALL queryAdapted() override;
@@ -98,23 +92,32 @@ Any SAL_CALL OWeakConnectionPoint::queryInterface( const Type & rType )
}
// XInterface
-void SAL_CALL OWeakConnectionPoint::acquire() throw()
+void SAL_CALL OWeakConnectionPoint::acquire() noexcept
{
+#ifdef DBG_UTIL
+ // catch things early which have been deleted and then re-acquired
+ assert(m_aRefCount != -1);
+#endif
osl_atomic_increment( &m_aRefCount );
}
// XInterface
-void SAL_CALL OWeakConnectionPoint::release() throw()
+void SAL_CALL OWeakConnectionPoint::release() noexcept
{
if (! osl_atomic_decrement( &m_aRefCount ))
+ {
+#ifdef DBG_UTIL
+ m_aRefCount = -1;
+#endif
delete this;
+ }
}
void OWeakConnectionPoint::dispose()
{
std::vector<Reference<XReference>> aCopy;
{ // only hold the mutex while we access the field
- MutexGuard aGuard(getWeakMutex());
+ std::scoped_lock aGuard(*cppu::gpWeakMutex);
// OWeakObject is not the only owner of this, so clear m_pObject
// so that queryAdapted() won't use it now that it's dead
m_pObject = nullptr;
@@ -146,40 +149,43 @@ Reference< XInterface > SAL_CALL OWeakConnectionPoint::queryAdapted()
{
Reference< XInterface > ret;
- ClearableMutexGuard guard(getWeakMutex());
-
- if (m_pObject)
{
+ std::scoped_lock guard(*gpWeakMutex);
+
+ if (!m_pObject)
+ return ret;
+
oslInterlockedCount n = osl_atomic_increment( &m_pObject->m_refCount );
- if (n > 1)
+ if (n <= 1)
{
- // The reference is incremented. The object cannot be destroyed.
- // Release the guard at the earliest point.
- guard.clear();
- // WeakObject has a (XInterface *) cast operator
- ret = *m_pObject;
- osl_atomic_decrement( &m_pObject->m_refCount );
- }
- else
// Another thread wait in the dispose method at the guard
osl_atomic_decrement( &m_pObject->m_refCount );
+ return ret;
+ }
}
+ // n is now > 1
+ // The reference is incremented. The object cannot be destroyed.
+ // Release the guard at the earliest point.
+ // WeakObject has a (XInterface *) cast operator
+ ret = *m_pObject;
+ osl_atomic_decrement( &m_pObject->m_refCount );
+
return ret;
}
// XInterface
void SAL_CALL OWeakConnectionPoint::addReference(const Reference< XReference >& rRef)
{
- MutexGuard aGuard(getWeakMutex());
+ std::scoped_lock aGuard(*gpWeakMutex);
m_aReferences.push_back( rRef );
}
// XInterface
void SAL_CALL OWeakConnectionPoint::removeReference(const Reference< XReference >& rRef)
{
- MutexGuard aGuard(getWeakMutex());
+ std::scoped_lock aGuard(*gpWeakMutex);
// 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.
@@ -198,16 +204,6 @@ void SAL_CALL OWeakConnectionPoint::removeReference(const Reference< XReference
//-- OWeakObject -------------------------------------------------------
-
-#ifdef _MSC_VER
-// Accidentally occurs in msvc mapfile = > had to be outlined.
-OWeakObject::OWeakObject()
- : m_refCount( 0 ),
- m_pWeakConnectionPoint( nullptr )
-{
-}
-#endif
-
// XInterface
Any SAL_CALL OWeakObject::queryInterface( const Type & rType )
{
@@ -217,13 +213,13 @@ Any SAL_CALL OWeakObject::queryInterface( const Type & rType )
}
// XInterface
-void SAL_CALL OWeakObject::acquire() throw()
+void SAL_CALL OWeakObject::acquire() noexcept
{
osl_atomic_increment( &m_refCount );
}
// XInterface
-void SAL_CALL OWeakObject::release() throw()
+void SAL_CALL OWeakObject::release() noexcept
{
if (osl_atomic_decrement( &m_refCount ) == 0) {
// notify/clear all weak-refs before object's dtor is executed
@@ -260,7 +256,7 @@ Reference< XAdapter > SAL_CALL OWeakObject::queryAdapter()
if (!m_pWeakConnectionPoint)
{
// only acquire mutex if member is not created
- MutexGuard aGuard( getWeakMutex() );
+ std::scoped_lock aGuard( *gpWeakMutex );
if( !m_pWeakConnectionPoint )
{
OWeakConnectionPoint * p = new OWeakConnectionPoint(this);
@@ -280,7 +276,7 @@ OWeakAggObject::~OWeakAggObject()
}
// XInterface
-void OWeakAggObject::acquire() throw()
+void OWeakAggObject::acquire() noexcept
{
Reference<XInterface > x( xDelegator );
if (x.is())
@@ -290,7 +286,7 @@ void OWeakAggObject::acquire() throw()
}
// XInterface
-void OWeakAggObject::release() throw()
+void OWeakAggObject::release() noexcept
{
Reference<XInterface > x( xDelegator );
if (x.is())
@@ -324,7 +320,6 @@ void OWeakAggObject::setDelegator( const Reference<XInterface > & rDelegator )
}
-/** */ //for docpp
namespace com::sun::star::uno
{
@@ -335,6 +330,7 @@ class OWeakRefListener final : public XReference
{
public:
explicit OWeakRefListener(const Reference< XInterface >& xInt);
+ explicit OWeakRefListener(const Reference< XWeak >& xInt);
virtual ~OWeakRefListener();
// noncopyable
@@ -343,8 +339,8 @@ public:
// XInterface
Any SAL_CALL queryInterface( const Type & rType ) override;
- void SAL_CALL acquire() throw() override;
- void SAL_CALL release() throw() override;
+ void SAL_CALL acquire() noexcept override;
+ void SAL_CALL release() noexcept override;
// XReference
void SAL_CALL dispose() override;
@@ -376,6 +372,18 @@ OWeakRefListener::OWeakRefListener(const Reference< XInterface >& xInt)
osl_atomic_decrement( &m_aRefCount );
}
+OWeakRefListener::OWeakRefListener(const Reference< XWeak >& xWeak)
+ : m_aRefCount( 1 )
+{
+ m_XWeakConnectionPoint = xWeak->queryAdapter();
+
+ if (m_XWeakConnectionPoint.is())
+ {
+ m_XWeakConnectionPoint->addReference(static_cast<XReference*>(this));
+ }
+ osl_atomic_decrement( &m_aRefCount );
+}
+
OWeakRefListener::~OWeakRefListener()
{
try
@@ -397,13 +405,13 @@ Any SAL_CALL OWeakRefListener::queryInterface( const Type & rType )
}
// XInterface
-void SAL_CALL OWeakRefListener::acquire() throw()
+void SAL_CALL OWeakRefListener::acquire() noexcept
{
osl_atomic_increment( &m_aRefCount );
}
// XInterface
-void SAL_CALL OWeakRefListener::release() throw()
+void SAL_CALL OWeakRefListener::release() noexcept
{
if( ! osl_atomic_decrement( &m_aRefCount ) )
delete this;
@@ -413,7 +421,7 @@ void SAL_CALL OWeakRefListener::dispose()
{
Reference< XAdapter > xAdp;
{
- MutexGuard guard(cppu::getWeakMutex());
+ std::scoped_lock guard(*cppu::gpWeakMutex);
if( m_XWeakConnectionPoint.is() )
{
xAdp = m_XWeakConnectionPoint;
@@ -438,6 +446,16 @@ WeakReferenceHelper::WeakReferenceHelper(const Reference< XInterface >& xInt)
}
}
+WeakReferenceHelper::WeakReferenceHelper(const Reference< XWeak >& xWeak)
+ : m_pImpl( nullptr )
+{
+ if (xWeak.is())
+ {
+ m_pImpl = new OWeakRefListener(xWeak);
+ m_pImpl->acquire();
+ }
+}
+
WeakReferenceHelper::WeakReferenceHelper(const WeakReferenceHelper& rWeakRef)
: m_pImpl( nullptr )
{
@@ -497,6 +515,18 @@ WeakReferenceHelper::operator= (const Reference< XInterface > & xInt)
return *this;
}
+WeakReferenceHelper &
+WeakReferenceHelper::operator= (const Reference< XWeak > & xWeak)
+{
+ clear();
+ if (xWeak)
+ {
+ m_pImpl = new OWeakRefListener(xWeak);
+ m_pImpl->acquire();
+ }
+ return *this;
+}
+
WeakReferenceHelper::~WeakReferenceHelper()
{
clear();
@@ -509,7 +539,7 @@ Reference< XInterface > WeakReferenceHelper::get() const
Reference< XAdapter > xAdp;
{
// must lock to access m_XWeakConnectionPoint
- MutexGuard guard(cppu::getWeakMutex());
+ std::scoped_lock guard(*cppu::gpWeakMutex);
if( m_pImpl && m_pImpl->m_XWeakConnectionPoint.is() )
xAdp = m_pImpl->m_XWeakConnectionPoint;
}