// 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 std::mutex * gpWeakMutex = new std::mutex;
/// Called from the weak object if the reference count goes to zero. /// /// @throws css::uno::RuntimeException void dispose();
private: virtual ~OWeakConnectionPoint() {}
/// The reference counter.
oslInterlockedCount m_aRefCount; /// The weak object
OWeakObject* m_pObject; /// The container to hold the weak references
std::vector<Reference<XReference>> m_aReferences;
};
// XInterface
Any SAL_CALL OWeakConnectionPoint::queryInterface( const Type & rType )
{ return ::cppu::queryInterface(
rType, static_cast< XAdapter * >( this ), static_cast< XInterface * >( this ) );
}
// XInterface 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 );
}
void OWeakConnectionPoint::dispose()
{
std::vector<Reference<XReference>> aCopy;
{ // only hold the mutex while we access the field
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; // 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<XReference> & i : aCopy )
{ try
{
i->dispose();
} catch (css::lang::DisposedException &) {} catch (RuntimeException &)
{
ex = cppu::getCaughtException();
}
} if (ex.hasValue())
{
cppu::throwException(ex);
}
}
oslInterlockedCount n = osl_atomic_increment( &m_pObject->m_refCount );
if (n <= 1)
{ // 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 );
// XInterface void SAL_CALL OWeakConnectionPoint::removeReference(const Reference< XReference >& rRef)
{
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. auto it = std::find_if(m_aReferences.rbegin(), m_aReferences.rend(),
[&rRef](const Reference<XReference>& rxRef) { return rxRef.get() == rRef.get(); }); if (it != m_aReferences.rend()) {
m_aReferences.erase( it.base()-1 ); return;
} // interface not found, use the correct compare method
it = std::find(m_aReferences.rbegin(), m_aReferences.rend(), rRef); if ( it != m_aReferences.rend() )
m_aReferences.erase( it.base()-1 );
}
/// The reference counter.
oslInterlockedCount m_aRefCount; /// The connection point of the weak object, guarded by getWeakMutex()
Reference< XAdapter > m_XWeakConnectionPoint;
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.