//! DEBUGGING ONLY: Get current strong ref count. int32_t getStrongCount() const;
classweakref_type { public: RefBase* refBase()const; voidincWeak(constvoid* id); voiddecWeak(constvoid* id); // acquires a strong reference if there is already one. boolattemptIncStrong(constvoid* id); // acquires a weak reference if there is already one. // This is not always safe. see ProcessState.cpp and BpBinder.cpp // for proper use. boolattemptIncWeak(constvoid* id);
//! DEBUGGING ONLY: Get current weak ref count. int32_t getWeakCount() const;
//! DEBUGGING ONLY: Print references held on object. voidprintRefs()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. voidtrackMe(bool enable, bool retain); }; weakref_type* createWeak(constvoid* id)const; weakref_type* getWeakRefs()const;
//! DEBUGGING ONLY: Print references held on object. inlinevoidprintRefs()const{ getWeakRefs()->printRefs(); }
void RefBase::incStrong(constvoid* id) const { weakref_impl* const refs = mRefs; refs->incWeak(id); refs->addStrongRef(id); constint32_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 = 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(); }
void RefBase::decStrong(constvoid* id) const { weakref_impl* const refs = mRefs; refs->removeStrongRef(id); constint32_t c = refs->mStrong.fetch_sub(1, std::memory_order_release); #if PRINT_REFS ALOGD("decStrong of %p from %p: cnt=%d\n", this, id, c); #endif 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) { deletethis; // 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); }
RefBase::~RefBase() { if (mRefs->mStrong.load(std::memory_order_relaxed) == INITIAL_STRONG_VALUE) { // we never acquired a strong (and/or weak) reference on this object. delete mRefs; } else { // life-time of this object is extended to WEAK, in // which case weakref_impl doesn't out-live the object and we // can free it now. int32_t flags = mRefs->mFlags.load(std::memory_order_relaxed); if ((flags & OBJECT_LIFETIME_MASK) != OBJECT_LIFETIME_STRONG) { // It's possible that the weak count is not 0 if the object // re-acquired a weak reference in its destructor if (mRefs->mWeak.load(std::memory_order_relaxed) == 0) { delete mRefs; } } } // for debugging purposes, clear this. const_cast<weakref_impl*&>(mRefs) = NULL; }
void RefBase::weakref_type::decWeak(constvoid* id) { weakref_impl* const impl = static_cast<weakref_impl*>(this); impl->removeWeakRef(id); constint32_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); // 1、生命周期受强引用计数控制 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. //2、没有被强引用引用过 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. // 如果对象生命周期受到弱引用控制,那么当弱引用为0时,delete impl->mBase impl->mBase->onLastWeakRef(id); delete impl->mBase; } }
ALOG_ASSERT(curCount >= 0, "attemptIncStrong called on %p after underflow", this);
//如果当前已经有其他强引用,那么对象一定存在,所以就试着将强引用引用计数+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. } //如果当前没有强引用的 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. //弱引用-1作回退 decWeak(id); returnfalse; }
// 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. // 强引用计数等于初始值,表示对象还没有强引用,自然也没有被销毁,可以转换,所以强引用+1,这里+1之后的值并不是1,而是 1<<28,所以在最后fetch_sub减掉了INITIAL_STRONG_VALUE 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); returnfalse; } } 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 // 询问是否允许升级到强指针,默认返回true表示允许,但是部分对象可能不允许做弱引用升级(重写该方法,返回false即可),如果不允许,那么久弱引用-1(回退第一步操作),直接然后返回false。如果允许弱引用升级,那么就强引用+1。 if (!impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id)) { // it didn't so give-up. decWeak(id); returnfalse; } // 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);
#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. // 如果之前没有过强引用,这里需要在强引用计数上减去1<<28。 if (curCount == INITIAL_STRONG_VALUE) { impl->mStrong.fetch_sub(INITIAL_STRONG_VALUE, std::memory_order_relaxed); }