зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1738106 - Part 2: Allow XPCOM classes to use SupportsThreadSafeWeakPtr, r=glandium,xpcom-reviewers
Due to how this type of threadsafe refcounting is implemented, it needs to be implemented using a MFBT-style refcounting base class, somewhat similar to `SupportsWeakPtr`. This patch makes NS_IMPL_{ADDREF,RELEASE}_INHERITED intelligently not add refcount logging for types inheriting from SupportsThreadSafeWeakPtr, as the default behaviour would break due to weak pointer upgrades not calling through `AddRef` or `Release`. In MFBT, the return value of `AddRef` and `Release` on SupportsThreadSafeWeakPtr is changed to be compatible with nsISupports, so that this type can be used to implement nsISupports refcounting. Differential Revision: https://phabricator.services.mozilla.com/D142603
This commit is contained in:
Родитель
2f853cadea
Коммит
18f7866fc2
|
@ -56,6 +56,7 @@
|
|||
#define mozilla_ThreadSafeWeakPtr_h
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/RefCountType.h"
|
||||
#include "mozilla/RefCounted.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
|
@ -151,14 +152,15 @@ class SupportsThreadSafeWeakPtr : public detail::SupportsThreadSafeWeakPtrBase {
|
|||
|
||||
public:
|
||||
// Compatibility with RefPtr
|
||||
void AddRef() const {
|
||||
MozExternalRefCountType AddRef() const {
|
||||
auto& refCnt = mWeakRef->mStrongCnt;
|
||||
MOZ_ASSERT(int32_t(refCnt) >= 0);
|
||||
MozRefCountType cnt = ++refCnt;
|
||||
detail::RefCountLogger::logAddRef(static_cast<const T*>(this), cnt);
|
||||
return cnt;
|
||||
}
|
||||
|
||||
void Release() const {
|
||||
MozExternalRefCountType Release() const {
|
||||
auto& refCnt = mWeakRef->mStrongCnt;
|
||||
MOZ_ASSERT(int32_t(refCnt) > 0);
|
||||
detail::RefCountLogger::ReleaseLogger logger(static_cast<const T*>(this));
|
||||
|
@ -176,6 +178,7 @@ class SupportsThreadSafeWeakPtr : public detail::SupportsThreadSafeWeakPtrBase {
|
|||
// it may still be read by mWeakRef.
|
||||
delete static_cast<const T*>(this);
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
// Compatibility with wtf::RefPtr
|
||||
|
|
|
@ -1354,14 +1354,26 @@ nsresult NS_FASTCALL NS_TableDrivenQI(void* aThis, REFNSIID aIID,
|
|||
|
||||
namespace mozilla {
|
||||
class Runnable;
|
||||
namespace detail {
|
||||
class SupportsThreadSafeWeakPtrBase;
|
||||
|
||||
// Don't NS_LOG_{ADDREF,RELEASE} when inheriting from `Runnable*` or types with
|
||||
// thread safe weak references, as it will generate incorrect refcnt logs due to
|
||||
// the thread-safe `Upgrade()` call's refcount modifications not calling through
|
||||
// the derived class' `AddRef()` and `Release()` methods.
|
||||
template <typename T>
|
||||
constexpr bool ShouldLogInheritedRefcnt =
|
||||
!std::is_convertible_v<T*, Runnable*> &&
|
||||
!std::is_base_of_v<SupportsThreadSafeWeakPtrBase, T>;
|
||||
}
|
||||
} // namespace mozilla
|
||||
|
||||
#define NS_IMPL_ADDREF_INHERITED_GUTS(Class, Super) \
|
||||
MOZ_ASSERT_TYPE_OK_FOR_REFCOUNTING(Class) \
|
||||
nsrefcnt r = Super::AddRef(); \
|
||||
if (!std::is_convertible_v<Class*, mozilla::Runnable*>) { \
|
||||
NS_LOG_ADDREF(this, r, #Class, sizeof(*this)); \
|
||||
} \
|
||||
#define NS_IMPL_ADDREF_INHERITED_GUTS(Class, Super) \
|
||||
MOZ_ASSERT_TYPE_OK_FOR_REFCOUNTING(Class) \
|
||||
nsrefcnt r = Super::AddRef(); \
|
||||
if constexpr (::mozilla::detail::ShouldLogInheritedRefcnt<Class>) { \
|
||||
NS_LOG_ADDREF(this, r, #Class, sizeof(*this)); \
|
||||
} \
|
||||
return r /* Purposefully no trailing semicolon */
|
||||
|
||||
#define NS_IMPL_ADDREF_INHERITED(Class, Super) \
|
||||
|
@ -1369,11 +1381,11 @@ class Runnable;
|
|||
NS_IMPL_ADDREF_INHERITED_GUTS(Class, Super); \
|
||||
}
|
||||
|
||||
#define NS_IMPL_RELEASE_INHERITED_GUTS(Class, Super) \
|
||||
nsrefcnt r = Super::Release(); \
|
||||
if (!std::is_convertible_v<Class*, mozilla::Runnable*>) { \
|
||||
NS_LOG_RELEASE(this, r, #Class); \
|
||||
} \
|
||||
#define NS_IMPL_RELEASE_INHERITED_GUTS(Class, Super) \
|
||||
nsrefcnt r = Super::Release(); \
|
||||
if constexpr (::mozilla::detail::ShouldLogInheritedRefcnt<Class>) { \
|
||||
NS_LOG_RELEASE(this, r, #Class); \
|
||||
} \
|
||||
return r /* Purposefully no trailing semicolon */
|
||||
|
||||
#define NS_IMPL_RELEASE_INHERITED(Class, Super) \
|
||||
|
|
Загрузка…
Ссылка в новой задаче