安卓系统中的智能指针
背景
在使用C++来编写代码的过程中,指针使用不当造成内存泄漏一般就是因为new了一个对象并且使用完之后,忘记了delete这个对象,而造成系统崩溃一般就是因为一个地方delete了这个对象之后,其它地方还在继续使原来指向这个对象的指针。为了避免出现上述问题,一般的做法就是使用引用计数的方法,每当有一个指针指向了一个new出来的对象时,就对这个对象的引用计数增加1,每当有一个指针不再使用这个对象时,就对这个对象的引用计数减少1,每次减1之后,如果发现引用计数值为0时,那么,就要delete这个对象了,这样就避免了忘记delete对象或者这个对象被delete之后其它地方还在使用的问题了。但是,如何实现这个对象的引用计数呢?肯定不是由开发人员来手动地维护了,要开发人员时刻记住什么时候该对这个对象的引用计数加1,什么时候该对这个对象的引用计数减1,一来是不方便开发,二来是不可靠,一不小心哪里多加了一个1或者多减了一个1,就会造成灾难性的后果。这时候,智能指针就粉墨登场了。首先,智能指针是一个对象,不过这个对象代表的是另外一个真实使用的对象,当智能指针指向实际对象的时候,就是智能指针对象创建的时候,当智能指针不再指向实际对象的时候,就是智能指针对象销毁的时候,我们知道,在C++中,对象的创建和销毁时会分别自动地调用对象的构造函数和析构函数,这样,负责对真实对象的引用计数加1和减1的工作就落实到智能指针对象的构造函数和析构函数的身上了,这也是为什么称这个指针对象为智能指针的原因。
在计算机科学领域中,提供垃圾收集(Garbage Collection)功能的系统框架,即提供对象托管功能的系统框架,例如Java应用程序框架,也是采用上述的引用计数技术方案来实现的,然而,简单的引用计数技术不能处理系统中对象间循环引用的情况。如:系统中有两个对象A和B,在对象A的内部引用了对象B,而在对象B的内部也引用了对象A。当两个对象A和B都不再使用时,垃圾收集系统会发现无法回收这两个对象的所占据的内存的,因为系统一次只能收集一个对象,而无论系统决定要收回对象A还是要收回对象B时,都会发现这个对象被其它的对象所引用,因而就都回收不了,这样就造成了内存泄漏。这样,就要采取另外的一种引用计数技术了,即对象的引用计数同时存在强引用和弱引用两种计数,例如,Apple公司提出的Cocoa框架,当父对象要引用子对象时,就对子对象使用强引用计数技术,而当子对象要引用父对象时,就对父对象使用弱引用计数技术,而当垃圾收集系统执行对象回收工作时,只要发现对象的强引用计数为0,而不管它的弱引用计数是否为0,都可以回收这个对象,但是,如果我们只对一个对象持有弱引用计数,当我们要使用这个对象时,就不直接使用了,必须要把这个弱引用升级成为强引用时,才能使用这个对象,在转换的过程中,如果对象已经不存在,那么转换就失败了,这时候就说明这个对象已经被销毁了,不能再使用了。
轻量级指针
引用计数器类LightRefBase,位置:system/core/include/utils/RefBase.h
template <class T>
class LightRefBase
{
public:
inline LightRefBase() : mCount(0) { }
inline void incStrong(__attribute__((unused)) const void* id) const {
mCount.fetch_add(1, std::memory_order_relaxed);
}
inline void decStrong(__attribute__((unused)) const void* id) const {
if (mCount.fetch_sub(1, std::memory_order_release) == 1) {
std::atomic_thread_fence(std::memory_order_acquire);
delete static_cast<const T*>(this);
}
}
//! DEBUGGING ONLY: Get current strong ref count.
inline int32_t getStrongCount() const {
return mCount.load(std::memory_order_relaxed);
}
typedef LightRefBase<T> basetype;
protected:
inline ~LightRefBase() { }
private:
friend class ReferenceMover;
inline static void renameRefs(size_t n, const ReferenceRenamer& renamer) { }
inline static void renameRefId(T* ref,
const void* old_id, const void* new_id) { }
private:
mutable std::atomic<int32_t> mCount;
};
unused:This attribute, attached to a function, means that the function is meant to be possibly unused. GCC will not produce a warning for this function
此类只有一个成员变量mCount
,即引用计数器,在构造方法中初始化为0。
此外,提供了incStrong和decStrong方法来操作此计数器的值。在decStrong方法中,若当前mCount的值为1,则delete此对象。
配合LightRefBase引用计数器使用的是sp类,位置:system/core/include/utils/StrongPointer.h
template<typename T>
class sp {
public:
inline sp() : m_ptr(0) { }
sp(T* other);
sp(const sp<T>& other);
sp(sp<T>&& other);
template<typename U> sp(U* other);
template<typename U> sp(const sp<U>& other);
template<typename U> sp(sp<U>&& other);
~sp();
// Assignment
sp& operator = (T* other);
sp& operator = (const sp<T>& other);
sp& operator = (sp<T>&& other);
template<typename U> sp& operator = (const sp<U>& other);
template<typename U> sp& operator = (sp<U>&& other);
template<typename U> sp& operator = (U* other);
//! Special optimization for use by ProcessState (and nobody else).
void force_set(T* other);
// Reset
void clear();
// Accessors
inline T& operator* () const { return *m_ptr; }
inline T* operator-> () const { return m_ptr; }
inline T* get() const { return m_ptr; }
// Operators
COMPARE(==)
COMPARE(!=)
COMPARE(>)
COMPARE(<)
COMPARE(<=)
COMPARE(>=)
private:
template<typename Y> friend class sp;
template<typename Y> friend class wp;
void set_pointer(T* ptr);
T* m_ptr;
};
同样,只看成员变量m_prt、构造函数、析构函数。
template<typename T>
sp<T>::sp(T* other)
: m_ptr(other) {
if (other)
other->incStrong(this);
}
template<typename T>
sp<T>::sp(const sp<T>& other)
: m_ptr(other.m_ptr) {
if (m_ptr)
m_ptr->incStrong(this);
}
template<typename T>
sp<T>::sp(sp<T>&& other)
: m_ptr(other.m_ptr) {
other.m_ptr = nullptr;
}
template<typename T> template<typename U>
sp<T>::sp(U* other)
: m_ptr(other) {
if (other)
((T*) other)->incStrong(this);
}
template<typename T> template<typename U>
sp<T>::sp(const sp<U>& other)
: m_ptr(other.m_ptr) {
if (m_ptr)
m_ptr->incStrong(this);
}
template<typename T> template<typename U>
sp<T>::sp(sp<U>&& other)
: m_ptr(other.m_ptr) {
other.m_ptr = nullptr;
}
构造方法中,都是先初始化m_ptr,然后调用incStrong
方法增加对象的引用计数。
template<typename T>
sp<T>::~sp() {
if (m_ptr)
m_ptr->decStrong(this);
}
析构函数中,调用decStrong
方法减少引用计数。
强指针
引用计数器类RefBase,所在位置:system/core/include/utils/RefBase.h
class RefBase
{
public:
void incStrong(const void* id) const;
void decStrong(const void* id) const;
void forceIncStrong(const void* id) const;
//! DEBUGGING ONLY: Get current strong ref count.
int32_t getStrongCount() const;
class weakref_type
{
public:
RefBase* refBase() const;
void incWeak(const void* id);
void decWeak(const void* id);
// acquires a strong reference if there is already one.
bool attemptIncStrong(const void* id);
// acquires a weak reference if there is already one.
// This is not always safe. see ProcessState.cpp and BpBinder.cpp
// for proper use.
bool attemptIncWeak(const void* id);
//! DEBUGGING ONLY: Get current weak ref count.
int32_t getWeakCount() const;
//! DEBUGGING ONLY: Print references held on object.
void printRefs() const;
//! DEBUGGING ONLY: Enable tracking for this object.
// enable -- enable/disable tracking
// retain -- when tracking is enable, if true, then we save a stack trace
// for each reference and dereference; when retain == false, we
// match up references and dereferences and keep only the
// outstanding ones.
void trackMe(bool enable, bool retain);
};
weakref_type* createWeak(const void* id) const;
weakref_type* getWeakRefs() const;
//! DEBUGGING ONLY: Print references held on object.
inline void printRefs() const { getWeakRefs()->printRefs(); }
//! DEBUGGING ONLY: Enable tracking of object.
inline void trackMe(bool enable, bool retain)
{
getWeakRefs()->trackMe(enable, retain);
}
typedef RefBase basetype;
protected:
RefBase();
virtual ~RefBase();
//! Flags for extendObjectLifetime()
enum {
OBJECT_LIFETIME_STRONG = 0x0000,
OBJECT_LIFETIME_WEAK = 0x0001,
OBJECT_LIFETIME_MASK = 0x0001
};
void extendObjectLifetime(int32_t mode);
//! Flags for onIncStrongAttempted()
enum {
FIRST_INC_STRONG = 0x0001
};
virtual void onFirstRef();
virtual void onLastStrongRef(const void* id);
virtual bool onIncStrongAttempted(uint32_t flags, const void* id);
virtual void onLastWeakRef(const void* id);
private:
friend class weakref_type;
class weakref_impl;
RefBase(const RefBase& o);
RefBase& operator=(const RefBase& o);
private:
friend class ReferenceMover;
static void renameRefs(size_t n, const ReferenceRenamer& renamer);
static void renameRefId(weakref_type* ref,
const void* old_id, const void* new_id);
static void renameRefId(RefBase* ref,
const void* old_id, const void* new_id);
weakref_impl* const mRefs;
};
与LightRefBase类一样,提供了incStrong和decStrong方法来操作计数器。与LightRefBase不同在于,他没有直接提供一直整型对象来维护计数器,而且通过weakref_impl
类型的成员变量mRefs
来维护计数器.
weakref_impl明显为实现类,位置:system/core.libutils/RefBase.cpp
class RefBase::weakref_impl : public RefBase::weakref_type
{
public:
std::atomic<int32_t> mStrong;
std::atomic<int32_t> mWeak;
RefBase* const mBase;
std::atomic<int32_t> mFlags;
weakref_impl(RefBase* base)
: mStrong(INITIAL_STRONG_VALUE)
, mWeak(0)
, mBase(base)
, mFlags(0)
{
}
void addStrongRef(const void* /*id*/) { }
void removeStrongRef(const void* /*id*/) { }
void renameStrongRefId(const void* /*old_id*/, const void* /*new_id*/) { }
void addWeakRef(const void* /*id*/) { }
void removeWeakRef(const void* /*id*/) { }
void renameWeakRefId(const void* /*old_id*/, const void* /*new_id*/) { }
void printRefs() const { }
void trackMe(bool, bool) { }
}
以上为release版本的代码,方法均为空方法。 此类中提供了4个成员变量来维护引用计数:
std::atomic<int32_t> mStrong;
std::atomic<int32_t> mWeak;
RefBase* const mBase;
std::atomic<int32_t> mFlags;
其中,mStrong
为对象的强引用计数,mWeak
为对象的若引用计数。mFlags
表示对象引用计数器所使用的策略,他的取值包括:
enum {
OBJECT_LIFETIME_STRONG = 0x0000,
OBJECT_LIFETIME_WEAK = 0x0001,
OBJECT_LIFETIME_MASK = 0x0001
};
// In the OBJECT_LIFETIME_STRONG case, it is deallocated in the RefBase
// destructor iff the strong reference count was never incremented. The
// destructor can be invoked either from decStrong, or from decWeak if there
// was never a strong reference. If the reference count had been incremented,
// it is deallocated directly in decWeak, and hence still lives as long as
// the last weak reference.
// In the OBJECT_LIFETIME_WEAK case, it is always deallocated from the RefBase
// destructor, which is always invoked by decWeak. DecStrong explicitly avoids
// the deletion in this case.
强指针类sp,构造方法的实现:
template<typename T>
sp<T>::sp(T* other)
: m_ptr(other)
{
if (other) other->incStrong(this);
}
other继承RefBase类,incStrong方法的实现:
void RefBase::incStrong(const void* id) const
{
weakref_impl* const refs = mRefs;
refs->incWeak(id);
refs->addStrongRef(id);
const int32_t c = refs->mStrong.fetch_add(1, std::memory_order_relaxed);
if (c != INITIAL_STRONG_VALUE) {
return;
}
int32_t old = refs->mStrong.fetch_sub(INITIAL_STRONG_VALUE,
std::memory_order_relaxed);
// A decStrong() must still happen after us.
refs->mBase->onFirstRef();
}
此方法中主要做了3件事:
1、增加弱引用计数;
weakref_impl* const refs = mRefs;
refs->incWeak(id);
2、增加强引用计数;
refs->addStrongRef(id);
const int32_t c = refs->mStrong.fetch_add(1, std::memory_order_relaxed);
3、判断是否为首次调用此对象的incStrong方法,如果是则调用对象的onFirstRef方法,让对象在被首次引用时做其他逻辑;
if (c != INITIAL_STRONG_VALUE) {
return;
}
int32_t old = refs->mStrong.fetch_sub(INITIAL_STRONG_VALUE,
std::memory_order_relaxed);
// A decStrong() must still happen after us.
refs->mBase->onFirstRef();
即:在构造方法中,强引用、弱引用计数+1。
强指针的析构函数:
template<typename T>
sp<T>::~sp() {
if (m_ptr)
m_ptr->decStrong(this);
}
m_ptr是继承RefBase类的对象,因此看RefBase重的decStrong方法。
void RefBase::decStrong(const void* id) const
{
weakref_impl* const refs = mRefs;
refs->removeStrongRef(id);
const int32_t c = refs->mStrong.fetch_sub(1, std::memory_order_release);
ALOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs);
if (c == 1) {
std::atomic_thread_fence(std::memory_order_acquire);
refs->mBase->onLastStrongRef(id);
int32_t flags = refs->mFlags.load(std::memory_order_relaxed);
if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
delete this;
// Since mStrong had been incremented, the destructor did not
// delete refs.
}
}
// Note that even with only strong reference operations, the thread
// deallocating this may not be the same as the thread deallocating refs.
// That's OK: all accesses to this happen before its deletion here,
// and all accesses to refs happen before its deletion in the final decWeak.
// The destructor can safely access mRefs because either it's deleting
// mRefs itself, or it's running entirely before the final mWeak decrement.
refs->decWeak(id);
}
在release版本中,removeStrongRef
方法为空实现,实现强引用计数器-1的为:
const int32_t c = refs->mStrong.fetch_sub(1, std::memory_order_release);
-1之前发现强引用计数为1,则表示再没有地方引用此对象了,看flags情况是否删除此对象。
if (c == 1) {
std::atomic_thread_fence(std::memory_order_acquire);
refs->mBase->onLastStrongRef(id);
int32_t flags = refs->mFlags.load(std::memory_order_relaxed);
if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
delete this;
// Since mStrong had been incremented, the destructor did not
// delete refs.
}
}
如果当前策略是OBJECT_LIFETIME_STRONG
,则直接删除此对象,否则执行
refs->decWeak(id)
decWeak的实现:
void RefBase::weakref_type::decWeak(const void* id)
{
weakref_impl* const impl = static_cast<weakref_impl*>(this);
impl->removeWeakRef(id);
const int32_t c = impl->mWeak.fetch_sub(1, std::memory_order_release);
ALOG_ASSERT(c >= 1, "decWeak called on %p too many times", this);
if (c != 1) return;
atomic_thread_fence(std::memory_order_acquire);
int32_t flags = impl->mFlags.load(std::memory_order_relaxed);
if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
// This is the regular lifetime case. The object is destroyed
// when the last strong reference goes away. Since weakref_impl
// outlive the object, it is not destroyed in the dtor, and
// we'll have to do it here.
if (impl->mStrong.load(std::memory_order_relaxed)
== INITIAL_STRONG_VALUE) {
// Special case: we never had a strong reference, so we need to
// destroy the object now.
delete impl->mBase;
} else {
// ALOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
delete impl;
}
} else {
// This is the OBJECT_LIFETIME_WEAK case. The last weak-reference
// is gone, we can destroy the object.
impl->mBase->onLastWeakRef(id);
delete impl->mBase;
}
}
同removeStrongRef
一样,真正实现若引用计数-1的为:
const int32_t c = impl->mWeak.fetch_sub(1, std::memory_order_release);
同时,-1之前判断是否为1,若不为1,则return。
if (c != 1) return;
如果对象的生命周期是受强引用计数器控制的,则:
if (impl->mStrong.load(std::memory_order_relaxed)
== INITIAL_STRONG_VALUE) {
// Special case: we never had a strong reference, so we need to
// destroy the object now.
delete impl->mBase;
} else {
// ALOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
delete impl;
}
在这里分了两种情况:
1、强引用计数==INITIAL_STRONG_VALUE
2、强引用计数!=INITIAL_STRONG_VALUE
增加对象的弱引用计数有两种方式:
1、增加对象的强引用计数时,会同时增加弱引用计数;
2、使用弱指针指向对象,只增加弱引用计数;
若为第一种方式,则强引用计数必然为0,!=INITIAL_STRONG_VALUE,则此时不需要删除此对象,因为decStrong方法中会删除此对象,此时只需要删除weakref_impl对象。
delete impl->mBase;
若为第二种方式,则表示没有地方会删除此对象,因此需要delete impl
.
即:
1、在OBJECT_LIFETIME_STRONG case下,强引用计数==0,delete此对象;
2、在OBJECT_LIFETIME_WEAK case下,强引用计数==0 && 弱引用计数==0,delete此对象。
弱指针
弱指针使用的引用计数器同强指针,是RefBase类。弱指针的位置:system/core/include/utils/RefBase.h
template <typename T>
class wp
{
public:
typedef typename RefBase::weakref_type weakref_type;
inline wp() : m_ptr(0) { }
wp(T* other);
wp(const wp<T>& other);
wp(const sp<T>& other);
template<typename U> wp(U* other);
template<typename U> wp(const sp<U>& other);
template<typename U> wp(const wp<U>& other);
~wp();
// Assignment
wp& operator = (T* other);
wp& operator = (const wp<T>& other);
wp& operator = (const sp<T>& other);
template<typename U> wp& operator = (U* other);
template<typename U> wp& operator = (const wp<U>& other);
template<typename U> wp& operator = (const sp<U>& other);
void set_object_and_refs(T* other, weakref_type* refs);
// promotion to sp
sp<T> promote() const;
// Reset
void clear();
// Accessors
inline weakref_type* get_refs() const { return m_refs; }
inline T* unsafe_get() const { return m_ptr; }
// Operators
COMPARE_WEAK(==)
COMPARE_WEAK(!=)
COMPARE_WEAK(>)
COMPARE_WEAK(<)
COMPARE_WEAK(<=)
COMPARE_WEAK(>=)
inline bool operator == (const wp<T>& o) const {
return (m_ptr == o.m_ptr) && (m_refs == o.m_refs);
}
template<typename U>
inline bool operator == (const wp<U>& o) const {
return m_ptr == o.m_ptr;
}
inline bool operator > (const wp<T>& o) const {
return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
}
template<typename U>
inline bool operator > (const wp<U>& o) const {
return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
}
inline bool operator < (const wp<T>& o) const {
return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
}
template<typename U>
inline bool operator < (const wp<U>& o) const {
return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
}
inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; }
template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); }
inline bool operator <= (const wp<T>& o) const { return !operator > (o); }
template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); }
inline bool operator >= (const wp<T>& o) const { return !operator < (o); }
template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); }
private:
template<typename Y> friend class sp;
template<typename Y> friend class wp;
T* m_ptr;
weakref_type* m_refs;
};
同强指针一样,m_ptr
变量指向目标对象。此外还有一个weakref_type
类型的成员变量m_refs
。
构造函数:
template<typename T>
wp<T>::wp(T* other)
: m_ptr(other)
{
if (other) m_refs = other->createWeak(this);
}
同强指针,other
是继承自RefBase
类,看RefBase
的createWeak
方法。
RefBase::weakref_type* RefBase::createWeak(const void* id) const
{
mRefs->incWeak(id);
return mRefs;
}
mRefs
为weakref_impl
的指针,incWeak
方法即为增加对象的弱引用计数。
void RefBase::weakref_type::incWeak(const void* id)
{
weakref_impl* const impl = static_cast<weakref_impl*>(this);
impl->addWeakRef(id);
const int32_t c __unused = impl->mWeak.fetch_add(1,
std::memory_order_relaxed);
ALOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);
}
析构函数:
template<typename T>
wp<T>::~wp()
{
if (m_ptr) m_refs->decWeak(this);
}
即RefBase
类的decWeak
方法,再强指针中已介绍。
弱指针的特点是不能直接操作目标对象,是因为没用重载*
和->
两个操作符。下面的是在StrongPointer中重载的操作符:
inline T& operator* () const { return *m_ptr; }
inline T* operator-> () const { return m_ptr; }
弱指针想要操作目标对象,可升级为强指针,通过如下方法:
template<typename T>
sp<T> wp<T>::promote() const
{
sp<T> result;
if (m_ptr && m_refs->attemptIncStrong(&result)) {
result.set_pointer(m_ptr);
}
return result;
}
attemptIncStrong
方法:
bool RefBase::weakref_type::attemptIncStrong(const void* id)
{
incWeak(id);
weakref_impl* const impl = static_cast<weakref_impl*>(this);
int32_t curCount = impl->mStrong.load(std::memory_order_relaxed);
ALOG_ASSERT(curCount >= 0,
"attemptIncStrong called on %p after underflow", this);
while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
// we're in the easy/common case of promoting a weak-reference
// from an existing strong reference.
if (impl->mStrong.compare_exchange_weak(curCount, curCount+1,
std::memory_order_relaxed)) {
break;
}
// the strong count has changed on us, we need to re-assert our
// situation. curCount was updated by compare_exchange_weak.
}
if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) {
// we're now in the harder case of either:
// - there never was a strong reference on us
// - or, all strong references have been released
int32_t flags = impl->mFlags.load(std::memory_order_relaxed);
if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
// this object has a "normal" life-time, i.e.: it gets destroyed
// when the last strong reference goes away
if (curCount <= 0) {
// the last strong-reference got released, the object cannot
// be revived.
decWeak(id);
return false;
}
// here, curCount == INITIAL_STRONG_VALUE, which means
// there never was a strong-reference, so we can try to
// promote this object; we need to do that atomically.
while (curCount > 0) {
if (impl->mStrong.compare_exchange_weak(curCount, curCount+1,
std::memory_order_relaxed)) {
break;
}
// the strong count has changed on us, we need to re-assert our
// situation (e.g.: another thread has inc/decStrong'ed us)
// curCount has been updated.
}
if (curCount <= 0) {
// promote() failed, some other thread destroyed us in the
// meantime (i.e.: strong count reached zero).
decWeak(id);
return false;
}
} else {
// this object has an "extended" life-time, i.e.: it can be
// revived from a weak-reference only.
// Ask the object's implementation if it agrees to be revived
if (!impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id)) {
// it didn't so give-up.
decWeak(id);
return false;
}
// grab a strong-reference, which is always safe due to the
// extended life-time.
curCount = impl->mStrong.fetch_add(1, std::memory_order_relaxed);
}
// If the strong reference count has already been incremented by
// someone else, the implementor of onIncStrongAttempted() is holding
// an unneeded reference. So call onLastStrongRef() here to remove it.
// (No, this is not pretty.) Note that we MUST NOT do this if we
// are in fact acquiring the first reference.
if (curCount > 0 && curCount < INITIAL_STRONG_VALUE) {
impl->mBase->onLastStrongRef(id);
}
}
impl->addStrongRef(id);
// curCount is the value of mStrong before we increment ed it.
// Now we need to fix-up the count if it was INITIAL_STRONG_VALUE.
// This must be done safely, i.e.: handle the case where several threads
// were here in attemptIncStrong().
// curCount > INITIAL_STRONG_VALUE is OK, and can happen if we're doing
// this in the middle of another incStrong. The subtraction is handled
// by the thread that started with INITIAL_STRONG_VALUE.
if (curCount == INITIAL_STRONG_VALUE) {
impl->mStrong.fetch_sub(INITIAL_STRONG_VALUE,
std::memory_order_relaxed);
}
return true;
}
此方法为增加对象的强引用计数,有可能因为目标对象已经被delete掉等原因失败。函数开始,即增加对象的弱引用计数,当之后增加强引用计数失败时,会减少弱引用计数。
incWeak(id);
增加强引用计数的时候,会有两种情况:
1、对象正在被其他强指针引用,即:强引用计数大于0并不等于INITIAL_STRONG_VALUE
2、对象未被其他强指针引用
当为第1种情况时,则直接增加其强引用计数:
while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
// we're in the easy/common case of promoting a weak-reference
// from an existing strong reference.
if (impl->mStrong.compare_exchange_weak(curCount, curCount+1,
std::memory_order_relaxed)) {
break;
}
// the strong count has changed on us, we need to re-assert our
// situation. curCount was updated by compare_exchange_weak.
}
当为第2种情况时,会有如下情况:
if(目标生命周期受强引用计数器控制){
if(强引用计数<=0){
decWeak(id);
return false;
}
增加强引用计数;
if(强引用计数<=0,即上一步增加失败){
decWeak(id);
return false;
}
}else 目标生命周期受弱引用计数器控制{
if(目标对象不允许onIncStrongAttempted){
decWeak(id);
return false;
}
增加强引用计数;
}
对应代码:
bool RefBase::weakref_type::attemptIncStrong(const void* id)
{
if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) {
// we're now in the harder case of either:
// - there never was a strong reference on us
// - or, all strong references have been released
int32_t flags = impl->mFlags.load(std::memory_order_relaxed);
//目标生命周期受强引用计数器控制
if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
// this object has a "normal" life-time, i.e.: it gets destroyed
// when the last strong reference goes away
//强引用计数<=0
if (curCount <= 0) {
// the last strong-reference got released, the object cannot
// be revived.
decWeak(id);
return false;
}
// here, curCount == INITIAL_STRONG_VALUE, which means
// there never was a strong-reference, so we can try to
// promote this object; we need to do that atomically.
//强引用计数>0
while (curCount > 0) {
if (impl->mStrong.compare_exchange_weak(curCount, curCount+1,
std::memory_order_relaxed)) {
break;
}
// the strong count has changed on us, we need to re-assert our
// situation (e.g.: another thread has inc/decStrong'ed us)
// curCount has been updated.
}
//增加失败
if (curCount <= 0) {
// promote() failed, some other thread destroyed us in the
// meantime (i.e.: strong count reached zero).
decWeak(id);
return false;
}
} else {
// this object has an "extended" life-time, i.e.: it can be
// revived from a weak-reference only.
// Ask the object's implementation if it agrees to be revived
//目标对象不允许onIncStrongAttempted
if (!impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id)) {
// it didn't so give-up.
decWeak(id);
return false;
}
// grab a strong-reference, which is always safe due to the
// extended life-time.
curCount = impl->mStrong.fetch_add(1, std::memory_order_relaxed);
}
// If the strong reference count has already been incremented by
// someone else, the implementor of onIncStrongAttempted() is holding
// an unneeded reference. So call onLastStrongRef() here to remove it.
// (No, this is not pretty.) Note that we MUST NOT do this if we
// are in fact acquiring the first reference.
if (curCount > 0 && curCount < INITIAL_STRONG_VALUE) {
impl->mBase->onLastStrongRef(id);
}
}
impl->addStrongRef(id);
// curCount is the value of mStrong before we increment ed it.
// Now we need to fix-up the count if it was INITIAL_STRONG_VALUE.
// This must be done safely, i.e.: handle the case where several threads
// were here in attemptIncStrong().
// curCount > INITIAL_STRONG_VALUE is OK, and can happen if we're doing
// this in the middle of another incStrong. The subtraction is handled
// by the thread that started with INITIAL_STRONG_VALUE.
if (curCount == INITIAL_STRONG_VALUE) {
impl->mStrong.fetch_sub(INITIAL_STRONG_VALUE,
std::memory_order_relaxed);
}
return true;
}