if (tr.target.ptr) { // We only have a weak reference on the target object, so we must first try to // safely acquire a strong reference before doing anything else with it. if (reinterpret_cast<RefBase::weakref_type*>( tr.target.ptr)->attemptIncStrong(this)) { error = reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer, &reply, tr.flags); reinterpret_cast<BBinder*>(tr.cookie)->decStrong(this); } else { error = UNKNOWN_TRANSACTION; } }
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; // 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. refs->decWeak(id); }
和其他智能指针的实现一样,这里把强引用计数减1。如果 c == 1,减 1 后强引用计数就是 0。也就是说,我们是最后一个指向这个对象的 sp。此时就得根据 mFlags 来决定如何处理了。
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; } } 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; } }
// system/core/libutils/RefBase.cpp RefBase::~RefBase() { int32_t flags = mRefs->mFlags.load(std::memory_order_relaxed); // 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. if ((flags & OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_WEAK) { // 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; } } elseif (mRefs->mStrong.load(std::memory_order_relaxed) == INITIAL_STRONG_VALUE) { // We never acquired a strong reference on this object. LOG_ALWAYS_FATAL_IF(mRefs->mWeak.load() != 0, "RefBase: Explicit destruction with non-zero weak " "reference count"); // TODO: Always report if we get here. Currently MediaMetadataRetriever // C++ objects are inconsistently managed and sometimes get here. // There may be other cases, but we believe they should all be fixed. delete mRefs; }
// 现在,我们尝试增加强引用计数 // 如果 curCount > 0 && curCount != INITIAL_STRONG_VALUE, // 说明当前有 sp 指向这个对象。 // 最好的(也是一般的)情况下,我们会在 sp 删除对象前,使得强引用计数+1, // 这样一来,我们的工作就结束了 // 注意:即使刚进来的时候 curCount > 0,在我们+1之前,也有可能变为 0 while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) { // we're in the easy/common case of promoting a weak-reference // from an existing strong reference. // 如果成功,返回 true // 如果失败,返回 false,同时修改 curCount 为当前值 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. }
// 如果上面的 while 成功,这里的 if 不会执行
// 1. 对象已经被释放,上面的 while 循环根本没有执行或执行过程中对象被释放,curCount <= 0 (其实只会等于 0) // 2. 目前没有强引用指向它 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 // OBJECT_LIFETIME_STRONG 并且 curCount <= 0 // 说明对象被某个 sp 释放了 if (curCount <= 0) { // the last strong-reference got released, the object cannot // be revived. // 一开始我们 incWeak,所以这里要减回去 decWeak(id); returnfalse; }
// 这里还没有 sp 指向对象,可以开始尝试增加强引用计数 // 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. }
// 在我们尝试增加强引用计数的时候,可能会有某个 sp 生成,而后销毁,导致我们增加强引用计数失败 if (curCount <= 0) { // promote() failed, some other thread destroyed us in the // meantime (i.e.: strong count reached zero). decWeak(id); returnfalse; } } else { // 这里是 OBJECT_LIFETIME_WEAK // 这种情况下,即使强引用计数为0,对象仍然不会被销毁 // 如果使用 RefBase 的默认实现onIncStrongAttempted() 将返回 true // 这是一个 virtual 函数,子类可以重写它 // 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); returnfalse; } // 现在,我们可以安全地使强引用计数加 1 了。 // 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); // nop
// 如果 curCount 是 INITIAL_STRONG_VALUE,而前面我们已经给他加1 // 所以 mStrong 现在是 (INITIAL_STRONG_VALUE+1) // 减去 INITIAL_STRONG_VALUE 后,就变为 1 // 刚好是我们返回的那个 sp 对应的强引用计数 // 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) { impl->mStrong.fetch_sub(INITIAL_STRONG_VALUE, std::memory_order_relaxed); }