/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
// 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;
class OWeakConnectionPoint: public XAdapter
{ public: /** Hold the weak object without an acquire (only the pointer).
*/ explicit OWeakConnectionPoint( OWeakObject* pObj )
: m_aRefCount( 0 )
, m_pObject(pObj)
{}
/// 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 ist noch experimentell.