From dfd4e75e6ef6e6d5c5da2569fba9f41876542ae5 Mon Sep 17 00:00:00 2001 From: "yaofeng.wang" Date: Mon, 7 Feb 2022 11:19:07 +0800 Subject: [PATCH] fixed 517ddc4 from https://gitee.com/jokerxd-liu/utils_native/pulls/57 Fix sptr multi-release point in concurrent environment 1. delete the strong reference when RefCount == 1 && !LifeTimeExtended 2. otherwise delete weak reference, when call DecWeakRef issue: https://gitee.com/openharmony/utils_native/issues/I4SK5B?from=project-issue Signed-off-by: yaofeng.wang --- base/include/refbase.h | 1 + base/src/refbase.cpp | 36 +++++++++++++++++++++++++++++++----- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/base/include/refbase.h b/base/include/refbase.h index 4b2b0d0..4c4c24b 100755 --- a/base/include/refbase.h +++ b/base/include/refbase.h @@ -28,6 +28,7 @@ class RefBase; class RefCounter { public: using RefPtrCallback = std::function; + friend class RefBase; RefCounter(); diff --git a/base/src/refbase.cpp b/base/src/refbase.cpp index d01f082..a05709e 100755 --- a/base/src/refbase.cpp +++ b/base/src/refbase.cpp @@ -148,12 +148,26 @@ int RefCounter::DecWeakRefCount(const void*) curCount = atomicWeak_.fetch_sub(1, std::memory_order_release); } - int strongRefCount = GetStrongRefCount(); - if ((curCount == 1) || (strongRefCount == 0 && !IsLifeTimeExtended())) { + if (curCount != 1) { + return curCount; + } + + if (IsLifeTimeExtended() && GetStrongRefCount() == 0) { if (callback_) { callback_(); } + } else { + // only weak ptr case: no strong reference, delete the object + if (GetStrongRefCount() == INITIAL_PRIMARY_VALUE) { + if (callback_) { + callback_(); + } + } else { + // free RefCounter + delete (this); + } } + return curCount; } @@ -299,7 +313,12 @@ RefBase::~RefBase() { if (refs_ != nullptr) { refs_->RemoveCallback(); - refs_->DecRefCount(); + if (refs_->IsLifeTimeExtended() && refs_->GetWeakRefCount() == 0) { + refs_->DecRefCount(); + } + if (refs_->GetStrongRefCount() == INITIAL_PRIMARY_VALUE) { + delete refs_; + } refs_ = nullptr; } } @@ -333,11 +352,18 @@ void RefBase::DecStrongRef(const void *objectId) return; } - const int curCount = refs_->DecStrongRefCount(objectId); + RefCounter *const refs = refs_; + const int curCount = refs->DecStrongRefCount(objectId); if (curCount == 1) { OnLastStrongRef(objectId); + if (!refs->IsLifeTimeExtended()) { + if (refs->callback_) { + refs->callback_(); + } + } } - DecWeakRef(objectId); + + refs->DecWeakRefCount(objectId); } int RefBase::GetSptrRefCount() -- Gitee