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 <wangyaofeng.wang@huawei.com>
This commit is contained in:
yaofeng.wang
2022-02-07 11:19:07 +08:00
parent fd96ee61da
commit 517ddc428b
2 changed files with 32 additions and 5 deletions
+1
View File
@@ -28,6 +28,7 @@ class RefBase;
class RefCounter {
public:
using RefPtrCallback = std::function<void()>;
friend class RefBase;
RefCounter();
+31 -5
View File
@@ -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()