diff --git a/base/include/refbase.h b/base/include/refbase.h index 4b2b0d03933b972e034349f7fc00dc544adc4e35..5c12a0ad6a47b9a51950c96cdbd2737be8cd1d5a 100755 --- a/base/include/refbase.h +++ b/base/include/refbase.h @@ -74,6 +74,7 @@ public: void ExtendObjectLifetime(); private: + friend class RefBase; std::atomic atomicStrong_; std::atomic atomicWeak_; std::atomic atomicRefCount_; diff --git a/base/src/refbase.cpp b/base/src/refbase.cpp index d01f08286d25f8d28c6d65bfdd018372071ad578..e24dfde93840d84b19a732ce1dfe2e821ee3f7c3 100755 --- a/base/src/refbase.cpp +++ b/base/src/refbase.cpp @@ -148,12 +148,16 @@ int RefCounter::DecWeakRefCount(const void*) curCount = atomicWeak_.fetch_sub(1, std::memory_order_release); } - int strongRefCount = GetStrongRefCount(); - if ((curCount == 1) || (strongRefCount == 0 && !IsLifeTimeExtended())) { - if (callback_) { - callback_(); + if (curCount == 1) { + if (IsLifeTimeExtended()) { + if (callback_) { + callback_(); + } + } else { + DecRefCount(); } } + return curCount; } @@ -299,9 +303,12 @@ RefBase::~RefBase() { if (refs_ != nullptr) { refs_->RemoveCallback(); - refs_->DecRefCount(); - refs_ = nullptr; + if (refs_->IsLifeTimeExtended() && refs_->GetWeakRefCount() == 0) { + refs_->DecRefCount(); + } } + + refs_ = nullptr; } void RefBase::ExtendObjectLifetime() @@ -333,11 +340,20 @@ void RefBase::DecStrongRef(const void *objectId) return; } - const int curCount = refs_->DecStrongRefCount(objectId); + RefCounter* refs = refs_; + const int curCount = refs->DecStrongRefCount(objectId); if (curCount == 1) { + std::atomic_thread_fence(std::memory_order_acquire); OnLastStrongRef(objectId); + if (!refs->IsLifeTimeExtended()) { + if (refs->callback_) { + // in this case, RefBase's destructor will not delete refs. + refs->callback_(); + } + } } - DecWeakRef(objectId); + + refs->DecWeakRefCount(objectId); } int RefBase::GetSptrRefCount()