Bug 1251559 - Remove the ownership of WeakPtr in SupportsWeakPtr. r=froydnj

--HG--
extra : rebase_source : 95c26d62cb6a39c9379bd1283d3446c44f1ac0b3
This commit is contained in:
JerryShih 2016-03-17 09:15:00 -04:00
Родитель 744871eb97
Коммит 45c666c953
1 изменённых файлов: 31 добавлений и 12 удалений

Просмотреть файл

@ -97,6 +97,14 @@ class WeakReference : public ::mozilla::RefCounted<WeakReference<T> >
{
public:
explicit WeakReference(T* p) : mPtr(p) {}
~WeakReference()
{
if (mPtr) {
// When this WeakReference is going to release, clear the WeakReference
// reference to this object in its referent |mPtr|.
mPtr->NoticeSelfReferencingDestruction();
}
}
T* get() const { return mPtr; }
@ -124,34 +132,49 @@ template <typename T>
class SupportsWeakPtr
{
protected:
SupportsWeakPtr()
: mSelfReferencingWeakPtr(nullptr)
{
}
~SupportsWeakPtr()
{
static_assert(IsBaseOf<SupportsWeakPtr<T>, T>::value,
"T must derive from SupportsWeakPtr<T>");
if (mSelfReferencingWeakPtr) {
mSelfReferencingWeakPtr.mRef->detach();
// When this SupportsWeakPtr is going to release, remove the referent
// reference to this object in WeakReference |mSelfReferencingWeakPtr|.
mSelfReferencingWeakPtr->detach();
mSelfReferencingWeakPtr = nullptr;
}
}
private:
const WeakPtr<T>& SelfReferencingWeakPtr()
detail::WeakReference<T>* SelfReferencingWeakPtr()
{
if (!mSelfReferencingWeakPtr) {
mSelfReferencingWeakPtr.mRef = new detail::WeakReference<T>(static_cast<T*>(this));
mSelfReferencingWeakPtr = new detail::WeakReference<T>(static_cast<T*>(this));
}
return mSelfReferencingWeakPtr;
}
const WeakPtr<const T>& SelfReferencingWeakPtr() const
detail::WeakReference<const T>* SelfReferencingWeakPtr() const
{
const WeakPtr<T>& p = const_cast<SupportsWeakPtr*>(this)->SelfReferencingWeakPtr();
return reinterpret_cast<const WeakPtr<const T>&>(p);
detail::WeakReference<T>* p = const_cast<SupportsWeakPtr*>(this)->SelfReferencingWeakPtr();
return reinterpret_cast<detail::WeakReference<const T>*>(p);
}
void NoticeSelfReferencingDestruction() const
{
mSelfReferencingWeakPtr = nullptr;
}
friend class WeakPtr<T>;
friend class WeakPtr<const T>;
friend class detail::WeakReference<T>;
friend class detail::WeakReference<const T>;
WeakPtr<T> mSelfReferencingWeakPtr;
mutable detail::WeakReference<T>* mSelfReferencingWeakPtr;
};
template <typename T>
@ -174,7 +197,7 @@ public:
WeakPtr& operator=(T* aOther)
{
if (aOther) {
*this = aOther->SelfReferencingWeakPtr();
mRef = aOther->SelfReferencingWeakPtr();
} else if (!mRef || mRef->get()) {
// Ensure that mRef is dereferenceable in the uninitialized state.
mRef = new WeakReference(nullptr);
@ -198,10 +221,6 @@ public:
T* get() const { return mRef->get(); }
private:
friend class SupportsWeakPtr<T>;
explicit WeakPtr(const RefPtr<WeakReference>& aOther) : mRef(aOther) {}
RefPtr<WeakReference> mRef;
};