mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-23 02:05:42 +00:00
Backed out changeset ddcc05491282 (bug 1207245)
This commit is contained in:
parent
c953b66104
commit
d22315fbb5
@ -62,6 +62,9 @@ protected:
|
||||
|
||||
public:
|
||||
// Mark user classes that are considered flawless.
|
||||
template<typename U>
|
||||
friend class RefPtr;
|
||||
|
||||
template<class U>
|
||||
friend class ::mozilla::StaticRefPtr;
|
||||
|
||||
|
@ -29,6 +29,8 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
template<typename T> class RefPtr;
|
||||
|
||||
/**
|
||||
* RefCounted<T> is a sort of a "mixin" for a class T. RefCounted
|
||||
* manages, well, refcounting for T, and because RefCounted is
|
||||
@ -90,6 +92,8 @@ enum RefCountAtomicity
|
||||
template<typename T, RefCountAtomicity Atomicity>
|
||||
class RefCounted
|
||||
{
|
||||
friend class RefPtr<T>;
|
||||
|
||||
protected:
|
||||
RefCounted() : mRefCnt(0) {}
|
||||
~RefCounted() { MOZ_ASSERT(mRefCnt == detail::DEAD); }
|
||||
|
210
mfbt/RefPtr.h
Normal file
210
mfbt/RefPtr.h
Normal file
@ -0,0 +1,210 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
/* Helpers for defining and using refcounted objects. */
|
||||
|
||||
#ifndef mozilla_RefPtr_h
|
||||
#define mozilla_RefPtr_h
|
||||
|
||||
#include "mozilla/AlreadyAddRefed.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Move.h"
|
||||
#include "mozilla/RefCounted.h"
|
||||
#include "mozilla/RefCountType.h"
|
||||
#include "mozilla/nsRefPtr.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
#if defined(MOZILLA_INTERNAL_API)
|
||||
#include "nsXPCOM.h"
|
||||
#endif
|
||||
|
||||
#if defined(MOZILLA_INTERNAL_API) && \
|
||||
!defined(MOZILLA_XPCOMRT_API) && \
|
||||
(defined(DEBUG) || defined(FORCE_BUILD_REFCNT_LOGGING))
|
||||
#define MOZ_REFCOUNTED_LEAK_CHECKING
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
template<typename T> class OutParamRef;
|
||||
template<typename T> OutParamRef<T> byRef(RefPtr<T>&);
|
||||
|
||||
/**
|
||||
* RefPtr points to a refcounted thing that has AddRef and Release
|
||||
* methods to increase/decrease the refcount, respectively. After a
|
||||
* RefPtr<T> is assigned a T*, the T* can be used through the RefPtr
|
||||
* as if it were a T*.
|
||||
*
|
||||
* A RefPtr can forget its underlying T*, which results in the T*
|
||||
* being wrapped in a temporary object until the T* is either
|
||||
* re-adopted from or released by the temporary.
|
||||
*/
|
||||
template<typename T>
|
||||
class RefPtr
|
||||
{
|
||||
// To allow them to use unref()
|
||||
friend class OutParamRef<T>;
|
||||
|
||||
struct DontRef {};
|
||||
|
||||
public:
|
||||
RefPtr() : mPtr(0) {}
|
||||
RefPtr(const RefPtr& aOther) : mPtr(ref(aOther.mPtr)) {}
|
||||
MOZ_IMPLICIT RefPtr(already_AddRefed<T>& aOther) : mPtr(aOther.take()) {}
|
||||
MOZ_IMPLICIT RefPtr(already_AddRefed<T>&& aOther) : mPtr(aOther.take()) {}
|
||||
MOZ_IMPLICIT RefPtr(T* aVal) : mPtr(ref(aVal)) {}
|
||||
|
||||
template<typename U>
|
||||
MOZ_IMPLICIT RefPtr(const RefPtr<U>& aOther) : mPtr(ref(aOther.get())) {}
|
||||
|
||||
~RefPtr() { unref(mPtr); }
|
||||
|
||||
RefPtr& operator=(const RefPtr& aOther)
|
||||
{
|
||||
assign(ref(aOther.mPtr));
|
||||
return *this;
|
||||
}
|
||||
RefPtr& operator=(already_AddRefed<T>& aOther)
|
||||
{
|
||||
assign(aOther.take());
|
||||
return *this;
|
||||
}
|
||||
RefPtr& operator=(already_AddRefed<T>&& aOther)
|
||||
{
|
||||
assign(aOther.take());
|
||||
return *this;
|
||||
}
|
||||
RefPtr& operator=(T* aVal)
|
||||
{
|
||||
assign(ref(aVal));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
RefPtr& operator=(const RefPtr<U>& aOther)
|
||||
{
|
||||
assign(ref(aOther.get()));
|
||||
return *this;
|
||||
}
|
||||
|
||||
already_AddRefed<T> forget()
|
||||
{
|
||||
T* tmp = mPtr;
|
||||
mPtr = nullptr;
|
||||
return already_AddRefed<T>(tmp);
|
||||
}
|
||||
|
||||
T* get() const { return mPtr; }
|
||||
operator T*() const
|
||||
#ifdef MOZ_HAVE_REF_QUALIFIERS
|
||||
&
|
||||
#endif
|
||||
{ return mPtr; }
|
||||
T* operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN { return mPtr; }
|
||||
T& operator*() const { return *mPtr; }
|
||||
|
||||
#ifdef MOZ_HAVE_REF_QUALIFIERS
|
||||
// Don't allow implicit conversion of temporary RefPtr to raw pointer, because
|
||||
// the refcount might be one and the pointer will immediately become invalid.
|
||||
operator T*() const && = delete;
|
||||
|
||||
// Needed to avoid the deleted operator above
|
||||
explicit operator bool() const { return !!mPtr; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
void assign(T* aVal)
|
||||
{
|
||||
T* tmp = mPtr;
|
||||
mPtr = aVal;
|
||||
unref(tmp);
|
||||
}
|
||||
|
||||
T* MOZ_OWNING_REF mPtr;
|
||||
|
||||
static MOZ_ALWAYS_INLINE T* ref(T* aVal)
|
||||
{
|
||||
if (aVal) {
|
||||
aVal->AddRef();
|
||||
}
|
||||
return aVal;
|
||||
}
|
||||
|
||||
static MOZ_ALWAYS_INLINE void unref(T* aVal)
|
||||
{
|
||||
if (aVal) {
|
||||
aVal->Release();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* OutParamRef is a wrapper that tracks a refcounted pointer passed as
|
||||
* an outparam argument to a function. OutParamRef implements COM T**
|
||||
* outparam semantics: this requires the callee to AddRef() the T*
|
||||
* returned through the T** outparam on behalf of the caller. This
|
||||
* means the caller (through OutParamRef) must Release() the old
|
||||
* object contained in the tracked RefPtr. It's OK if the callee
|
||||
* returns the same T* passed to it through the T** outparam, as long
|
||||
* as the callee obeys the COM discipline.
|
||||
*
|
||||
* Prefer returning already_AddRefed<T> from functions over creating T**
|
||||
* outparams and passing OutParamRef<T> to T**. Prefer RefPtr<T>*
|
||||
* outparams over T** outparams.
|
||||
*/
|
||||
template<typename T>
|
||||
class OutParamRef
|
||||
{
|
||||
friend OutParamRef byRef<T>(RefPtr<T>&);
|
||||
|
||||
public:
|
||||
~OutParamRef()
|
||||
{
|
||||
RefPtr<T>::unref(mRefPtr.mPtr);
|
||||
mRefPtr.mPtr = mTmp;
|
||||
}
|
||||
|
||||
operator T**() { return &mTmp; }
|
||||
|
||||
private:
|
||||
explicit OutParamRef(RefPtr<T>& p) : mRefPtr(p), mTmp(p.get()) {}
|
||||
|
||||
RefPtr<T>& mRefPtr;
|
||||
T* mTmp;
|
||||
|
||||
OutParamRef() = delete;
|
||||
OutParamRef& operator=(const OutParamRef&) = delete;
|
||||
};
|
||||
|
||||
/**
|
||||
* byRef cooperates with OutParamRef to implement COM outparam semantics.
|
||||
*/
|
||||
template<typename T>
|
||||
OutParamRef<T>
|
||||
byRef(RefPtr<T>& aPtr)
|
||||
{
|
||||
return OutParamRef<T>(aPtr);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
// Declared in nsRefPtr.h
|
||||
template<class T> template<class U>
|
||||
nsRefPtr<T>::nsRefPtr(mozilla::RefPtr<U>&& aOther)
|
||||
: nsRefPtr(aOther.forget())
|
||||
{
|
||||
}
|
||||
|
||||
template<class T> template<class U>
|
||||
nsRefPtr<T>&
|
||||
nsRefPtr<T>::operator=(mozilla::RefPtr<U>&& aOther)
|
||||
{
|
||||
assign_assuming_AddRef(aOther.forget().take());
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif /* mozilla_RefPtr_h */
|
@ -70,6 +70,7 @@ EXPORTS.mozilla = [
|
||||
'RefCounted.h',
|
||||
'RefCountType.h',
|
||||
'ReentrancyGuard.h',
|
||||
'RefPtr.h',
|
||||
'ReverseIterator.h',
|
||||
'RollingMean.h',
|
||||
'Scoped.h',
|
||||
|
@ -19,6 +19,7 @@ class nsCOMPtr_helper;
|
||||
|
||||
namespace mozilla {
|
||||
template<class T> class OwningNonNull;
|
||||
template<class T> class RefPtr;
|
||||
} // namespace mozilla
|
||||
|
||||
template <class T>
|
||||
@ -127,6 +128,10 @@ public:
|
||||
template<class U>
|
||||
MOZ_IMPLICIT nsRefPtr(const mozilla::OwningNonNull<U>& aOther);
|
||||
|
||||
// Defined in RefPtr.h
|
||||
template<class U>
|
||||
MOZ_IMPLICIT nsRefPtr(mozilla::RefPtr<U>&& aOther);
|
||||
|
||||
// Assignment operators
|
||||
|
||||
nsRefPtr<T>&
|
||||
@ -187,6 +192,11 @@ public:
|
||||
nsRefPtr<T>&
|
||||
operator=(const mozilla::OwningNonNull<U>& aOther);
|
||||
|
||||
// Defined in RefPtr.h
|
||||
template<class U>
|
||||
nsRefPtr<T>&
|
||||
operator=(mozilla::RefPtr<U>&& aOther);
|
||||
|
||||
// Other pointer operators
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user