本篇介紹
android中有三種智能指針,分別是輕量級(jí)指針,強(qiáng)指針,弱指針。輕量級(jí)指針實(shí)現(xiàn)簡(jiǎn)潔,效果類似于強(qiáng)指針,然后強(qiáng)指針和弱指針的實(shí)現(xiàn)比較復(fù)雜比較重一些。本篇就介紹下這三種指針的具體實(shí)現(xiàn)。
輕量級(jí)指針
輕量級(jí)指針在Android中是由LightRefBase來(lái)提供的,看下內(nèi)容:
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 incStrongRequireStrong(__attribute__((unused)) const void* id) const {
if (0 == mCount.fetch_add(1, std::memory_order_relaxed)) {
LightRefBase_reportIncStrongRequireStrongFailed(this);
}
}
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);
}
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;
};
一個(gè)類只要繼承LightRefBase,然后配合sp就可以使用智能指針的功能了。sp后面會(huì)單獨(dú)介紹。
從這兒可以看出來(lái),輕量級(jí)指針主要是在類里面添加了一個(gè)原子變量作為計(jì)數(shù)變量,然后通過(guò)incStrong和decStrong來(lái)實(shí)現(xiàn)計(jì)數(shù)的增減。
這兒有一個(gè)細(xì)節(jié)是這個(gè)計(jì)數(shù)可能會(huì)在多個(gè)線程里面訪問(wèn),因此就會(huì)出現(xiàn)并發(fā)問(wèn)題。比如一個(gè)對(duì)象對(duì)應(yīng)的多個(gè)智能指針在多個(gè)線程里面使用,這時(shí)候就需要某個(gè)機(jī)制可以保證計(jì)數(shù)的準(zhǔn)確。具體的策略就在incStrong和decStong里面,可以看到主要是使用了原子操作,并指定了內(nèi)存序。這樣通過(guò)內(nèi)存屏障手段實(shí)現(xiàn)了不用持鎖也能實(shí)現(xiàn)一致性。
接下來(lái)看下sp,一個(gè)類繼承了LightRefBase后就擁有了智能指針計(jì)數(shù)機(jī)制,然后通過(guò)sp來(lái)操作指針才能實(shí)現(xiàn)智能管理內(nèi)存的效果:
template<typename T>
class sp {
public:
inline sp() : m_ptr(0) { }
sp(T* other); // NOLINT(implicit)
sp(const sp<T>& other);
sp(sp<T>&& other);
template<typename U> sp(U* other); // NOLINT(implicit)
template<typename U> sp(const sp<U>& other); // NOLINT(implicit)
template<typename U> sp(sp<U>&& other); // NOLINT(implicit)
~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; }
inline explicit operator bool () const { return m_ptr != nullptr; }
// 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;
};
可以看到sp定義了對(duì)指針的基本操作,并通過(guò)m_ptr保存所管理的對(duì)象指針,看下構(gòu)造和析構(gòu)方法:
template<typename T>
sp<T>::sp(T* other)
: m_ptr(other) {
if (other)
other->incStrong(this);
}
初始化m_ptr,然后調(diào)用incStrong增加計(jì)數(shù),其實(shí)就是調(diào)用LightRefBase的incStrong,再看下移動(dòng)拷貝構(gòu)造函數(shù):
template<typename T>
sp<T>::sp(sp<T>&& other)
: m_ptr(other.m_ptr) {
other.m_ptr = nullptr;
}
移動(dòng)只涉及擁有權(quán)的轉(zhuǎn)移,因此不能更新計(jì)數(shù)。
其他構(gòu)造函數(shù)也類似,再看下析構(gòu)函數(shù):
template<typename T>
sp<T>::~sp() {
if (m_ptr)
m_ptr->decStrong(this);
}
析構(gòu)就是減少計(jì)數(shù),調(diào)用LightRefBase的decStrong,看下對(duì)應(yīng)的實(shí)現(xiàn):
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);
}
}
對(duì)計(jì)數(shù)減1,如果計(jì)數(shù)已經(jīng)是1了,難么減少后就是0,就需要調(diào)用下析構(gòu),把對(duì)象釋放掉。
強(qiáng)指針
強(qiáng)指針和弱指針對(duì)應(yīng)的結(jié)構(gòu)都是RefBase:
class RefBase
{
public:
void incStrong(const void* id) const;
void incStrongRequireStrong(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 incWeakRequireWeak(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);
}
protected:
// When constructing these objects, prefer using sp::make<>. Using a RefBase
// object on the stack or with other refcount mechanisms (e.g.
// std::shared_ptr) is inherently wrong. RefBase types have an implicit
// ownership model and cannot be safely used with other ownership models.
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
};
// Invoked after creation of initial strong pointer/reference.
virtual void onFirstRef();
// Invoked when either the last strong reference goes away, or we need to undo
// the effect of an unnecessary onIncStrongAttempted.
virtual void onLastStrongRef(const void* id);
// Only called in OBJECT_LIFETIME_WEAK case. Returns true if OK to promote to
// strong reference. May have side effects if it returns true.
// The first flags argument is always FIRST_INC_STRONG.
// TODO: Remove initial flag argument.
virtual bool onIncStrongAttempted(uint32_t flags, const void* id);
// Invoked in the OBJECT_LIFETIME_WEAK case when the last reference of either
// kind goes away. Unused.
// TODO: Remove.
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;
};
可以看到對(duì)于強(qiáng)指針,并不是簡(jiǎn)單用一個(gè)原子變量來(lái)計(jì)數(shù)了,而是使用了weakref_impl,這是一個(gè)weakref_type類型,定義如下:
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;
explicit 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) { }
可以看到RefBase提供了更多的能力,一個(gè)類繼承了RefBase就可以通過(guò)強(qiáng)指針和弱指針來(lái)使用了。強(qiáng)指針就是前面提到的sp,關(guān)鍵的還是incStrong和decStrong,現(xiàn)在再看下流程, 對(duì)于sp的incStorng,調(diào)用的是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);
ALOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs);
#if PRINT_REFS
ALOGD("incStrong of %p from %p: cnt=%d\n", this, id, c);
#endif
if (c != INITIAL_STRONG_VALUE) {
return;
}
int32_t old __unused = refs->mStrong.fetch_sub(INITIAL_STRONG_VALUE, std::memory_order_relaxed);
// A decStrong() must still happen after us.
ALOG_ASSERT(old > INITIAL_STRONG_VALUE, "0x%x too small", old);
refs->mBase->onFirstRef();
}
可以看到先增加了弱引用,然后又添加了強(qiáng)引用,不過(guò)這兒并不是增加計(jì)數(shù),而是記錄引用指針,接下來(lái)才是增加計(jì)數(shù),如果不是首次增加就直接返回了,否則會(huì)調(diào)用onFirstRef。這樣如果有類想在第一次被引用的時(shí)候做些邏輯就可以使用這個(gè)機(jī)制了。
接下來(lái)看下incWeak和addStrongRef:
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); // 增加計(jì)數(shù)
ALOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);
}
void addWeakRef(const void* id) {
addRef(&mWeakRefs, id, mWeak.load(std::memory_order_relaxed));
}
void addStrongRef(const void* id) {
//ALOGD_IF(mTrackEnabled,
// "addStrongRef: RefBase=%p, id=%p", mBase, id);
addRef(&mStrongRefs, id, mStrong.load(std::memory_order_relaxed));
}
// 記錄引用快照,這里面的引用計(jì)數(shù)是引用當(dāng)時(shí)的計(jì)數(shù),后續(xù)不會(huì)更新
void addRef(ref_entry** refs, const void* id, int32_t mRef)
{
if (mTrackEnabled) {
AutoMutex _l(mMutex);
ref_entry* ref = new ref_entry;
// Reference count at the time of the snapshot, but before the
// update. Positive value means we increment, negative--we
// decrement the reference count.
ref->ref = mRef;
ref->id = id;
#if DEBUG_REFS_CALLSTACK_ENABLED
ref->stack = CallStack::getCurrent(2);
#endif
ref->next = *refs;
*refs = ref;
}
}
看到這兒基本就把添加引用流程走完了,從這兒也可以看出來(lái)弱引用計(jì)數(shù)一定大于等于強(qiáng)引用計(jì)數(shù)。
再看下decStrong,調(diào)用的也是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); // 強(qiáng)引用計(jì)數(shù)減1
#if PRINT_REFS
ALOGD("decStrong of %p from %p: cnt=%d\n", this, id, c);
#endif
LOG_ALWAYS_FATAL_IF(BAD_STRONG(c), "decStrong() called on %p too many times",
refs);
if (c == 1) {
std::atomic_thread_fence(std::memory_order_acquire);
refs->mBase->onLastStrongRef(id); // 如果最后一個(gè)強(qiáng)引用,則調(diào)用下onLastStrongRef
int32_t flags = refs->mFlags.load(std::memory_order_relaxed);
if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
delete this; // 如果是強(qiáng)引用關(guān)聯(lián)對(duì)象模式,則強(qiáng)引用為0時(shí)調(diào)用對(duì)象的析構(gòu)函數(shù)
// The destructor does not delete refs in this case.
}
}
// 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.
//
// Since we're doing atomic loads of `flags`, the static analyzer assumes
// they can change between `delete this;` and `refs->decWeak(id);`. This is
// not the case. The analyzer may become more okay with this patten when
// https://bugs.llvm.org/show_bug.cgi?id=34365 gets resolved. NOLINTNEXTLINE
refs->decWeak(id); // 減少弱引用
}
可以看到decStrong中的邏輯主要就是操作強(qiáng)引用計(jì)數(shù)和弱引用計(jì)數(shù)。再看下移除引用和減少弱引用的實(shí)現(xiàn):
void removeStrongRef(const void* id) {
//ALOGD_IF(mTrackEnabled,
// "removeStrongRef: RefBase=%p, id=%p", mBase, id);
if (!mRetain) {
removeRef(&mStrongRefs, id);
} else {
addRef(&mStrongRefs, id, -mStrong.load(std::memory_order_relaxed));
}
}
void removeRef(ref_entry** refs, const void* id) // 移除引用
{
if (mTrackEnabled) {
AutoMutex _l(mMutex);
ref_entry* const head = *refs;
ref_entry* ref = head;
while (ref != NULL) {
if (ref->id == id) {
*refs = ref->next;
delete ref;
return;
}
refs = &ref->next;
ref = *refs;
}
ALOGE("RefBase: removing id %p on RefBase %p"
"(weakref_type %p) that doesn't exist!",
id, mBase, this);
ref = head;
while (ref) {
char inc = ref->ref >= 0 ? '+' : '-';
ALOGD("\t%c ID %p (ref %d):", inc, ref->id, ref->ref);
ref = ref->next;
}
CallStack::logStack(LOG_TAG);
}
}
再看下減少弱引用實(shí)現(xiàn):
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); // 弱引用減1
LOG_ALWAYS_FATAL_IF(BAD_WEAK(c), "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
// outlives 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) {
// Decrementing a weak count to zero when object never had a strong
// reference. We assume it acquired a weak reference early, e.g.
// in the constructor, and will eventually be properly destroyed,
// usually via incrementing and decrementing the strong count.
// Thus we no longer do anything here. We log this case, since it
// seems to be extremely rare, and should not normally occur. We
// used to deallocate mBase here, so this may now indicate a leak.
ALOGW("RefBase: Object at %p lost last weak reference "
"before it had a strong reference", impl->mBase);
} else {
// ALOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
delete impl; // 弱應(yīng)用為0了,刪除析構(gòu)智能指針本身
}
} else {
// This is the OBJECT_LIFETIME_WEAK case. The last weak-reference
// is gone, we can destroy the object. // 如果是對(duì)象管理和弱引用關(guān)聯(lián),那么弱引用計(jì)數(shù)為0時(shí),需要析構(gòu)管理的對(duì)象。
impl->mBase->onLastWeakRef(id);
delete impl->mBase;
}
}
到了這兒decStrong流程就結(jié)束了,主要就是減少?gòu)?qiáng)弱引用計(jì)數(shù)的值,并且在引用計(jì)數(shù)為0時(shí)按照對(duì)象管理策略進(jìn)行析構(gòu)對(duì)象。
弱指針
再看下弱指針的實(shí)現(xiàn),弱指針比較復(fù)雜一些:
template <typename T>
class wp
{
public:
typedef typename RefBase::weakref_type weakref_type;
inline wp() : m_ptr(nullptr), m_refs(nullptr) { }
wp(T* other); // NOLINT(implicit)
wp(const wp<T>& other);
explicit wp(const sp<T>& other);
template<typename U> wp(U* other); // NOLINT(implicit)
template<typename U> wp(const sp<U>& other); // NOLINT(implicit)
template<typename U> wp(const wp<U>& other); // NOLINT(implicit)
~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; // 由弱指針獲取一個(gè)強(qiáng)指針
// 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_FUNCTIONAL(>, std::greater)
COMPARE_WEAK_FUNCTIONAL(<, std::less)
COMPARE_WEAK_FUNCTIONAL(<=, std::less_equal)
COMPARE_WEAK_FUNCTIONAL(>=, std::greater_equal)
template<typename U>
inline bool operator == (const wp<U>& o) const {
return m_refs == o.m_refs; // Implies m_ptr == o.mptr; see invariants below.
}
template<typename U>
inline bool operator == (const sp<U>& o) const {
// Just comparing m_ptr fields is often dangerous, since wp<> may refer to an older
// object at the same address.
if (o == nullptr) {
return m_ptr == nullptr;
} else {
return m_refs == o->getWeakRefs(); // Implies m_ptr == o.mptr.
}
}
template<typename U>
inline bool operator != (const sp<U>& o) const {
return !(*this == o);
}
template<typename U>
inline bool operator > (const wp<U>& o) const {
if (m_ptr == o.m_ptr) {
return _wp_compare_<std::greater>(m_refs, o.m_refs);
} else {
return _wp_compare_<std::greater>(m_ptr, o.m_ptr);
}
}
template<typename U>
inline bool operator < (const wp<U>& o) const {
if (m_ptr == o.m_ptr) {
return _wp_compare_<std::less>(m_refs, o.m_refs);
} else {
return _wp_compare_<std::less>(m_ptr, o.m_ptr);
}
}
template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); }
template<typename U> inline bool operator <= (const wp<U>& 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;
};
可以看到2點(diǎn):
- 弱指針計(jì)數(shù)也是基于weakref_type,實(shí)際上就是weakref_impl,并不是自己維護(hù)一個(gè)計(jì)數(shù)
- 弱指針沒(méi)有重載指針解引用等通過(guò)指針操作對(duì)象對(duì)象的運(yùn)算符,這樣通過(guò)弱引用就無(wú)法直接操作對(duì)象了。需要通過(guò)一個(gè)專門(mén)的函數(shù)promote獲取強(qiáng)指針才可以。
接下來(lái)還是看三塊內(nèi)容,構(gòu)造,析構(gòu),promote。先看下構(gòu)造:
wp<T>::wp(T* other)
: m_ptr(other)
{
m_refs = other ? m_refs = other->createWeak(this) : nullptr;
}
m_ptr 保存對(duì)象指針,m_refs負(fù)責(zé)計(jì)數(shù),看下createWeak的實(shí)現(xiàn):
RefBase::weakref_type* RefBase::createWeak(const void* id) const
{
mRefs->incWeak(id); // 添加引用,弱引用計(jì)數(shù)加1
return mRefs;
}
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);
}
再看下析構(gòu):
wp<T>::~wp()
{
if (m_ptr) m_refs->decWeak(this); // 減少弱引用計(jì)數(shù)
}
再看下promote:
sp<T> wp<T>::promote() const
{
sp<T> result;
if (m_ptr && m_refs->attemptIncStrong(&result)) {
result.set_pointer(m_ptr); // 因?yàn)閺?qiáng)引用計(jì)數(shù)已經(jīng)增加了,這兒只需要設(shè)置下對(duì)象指針
}
return result;
}
通過(guò)attemptIncStrong嘗試修改強(qiáng)引用計(jì)數(shù):
bool RefBase::weakref_type::attemptIncStrong(const void* id)
{
incWeak(id); // 弱引用計(jì)數(shù)加1
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);
// 如果當(dāng)前強(qiáng)引用計(jì)數(shù)大于0,那么所管理的對(duì)象是有效的,那么更新強(qiáng)引用計(jì)數(shù)。
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); // 如果強(qiáng)引用計(jì)數(shù)不大于0,而且是OBJECT_LIFETIME_STRONG,那么這時(shí)候?qū)ο笠呀?jīng)釋放了,獲取不到強(qiáng)指針了,把之前的弱引用加的計(jì)數(shù)減回去
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) { // 嘗試增加強(qiáng)引用計(jì)數(shù)
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) { // 增加強(qiáng)引用計(jì)數(shù)失敗了
// promote() failed, some other thread destroyed us in the
// meantime (i.e.: strong count reached zero).
decWeak(id);
return false;
}
} else { // 這時(shí)候是由弱引用決定對(duì)象釋放時(shí)間點(diǎn),因此這時(shí)候?qū)ο罂赡軟](méi)有被釋放
// 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)) { // 是否允許通過(guò)弱指針獲取強(qiáng)指針,目前的實(shí)現(xiàn)是一定會(huì)返回允許
// 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); // 增加強(qiáng)引用計(jì)數(shù)
// 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); // 記錄強(qiáng)引用
#if PRINT_REFS
ALOGD("attemptIncStrong of %p from %p: cnt=%d\n", this, id, curCount);
#endif
// curCount is the value of mStrong before we incremented 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) { // 如果是首次增加,那么需要調(diào)整計(jì)數(shù),因?yàn)殚_(kāi)始默認(rèn)值是INITIAL_STRONG_VALUE, 需要把這個(gè)數(shù)減掉才是正確的計(jì)數(shù)值
impl->mStrong.fetch_sub(INITIAL_STRONG_VALUE,
std::memory_order_relaxed);
}
return true;
}
到了這兒關(guān)于弱指針的內(nèi)容也介紹完了。
最后畫(huà)一個(gè)圖總結(jié)下輕量級(jí)指針,強(qiáng)指針,弱指針的關(guān)系:
