diff --git a/base/include/refbase.h b/base/include/refbase.h index 0a3a86f040736b15caa9d4b9b1d90e36f0634e53..65658b263d1eb23b74dba5635b8e094698506f29 100644 --- a/base/include/refbase.h +++ b/base/include/refbase.h @@ -184,6 +184,11 @@ public: */ void SetAttemptAcquire(); + /** + * @brief Get the current times of attempts. + */ + int GetAttemptAcquire(); + /** * @brief Check if the number of attempts is greater than 0. * @@ -490,6 +495,15 @@ public: */ bool AttemptAcquire(const void *objectId); + // Only for IPC use. + /** + * @brief Check attempt acquire is setted + * + * @note This fuction is extracted from `IncStrongRef()` + * It is only for IPC use. + */ + void CheckIsAttemptAcquireSet(const void *objectId); + /** * @brief Attempts to increment the count of strong references. * diff --git a/base/src/refbase.cpp b/base/src/refbase.cpp index affddd942903cd1020d948dca3b24427740820c1..9d5848069c3a50b6574378c7da17fec15ac3f610 100644 --- a/base/src/refbase.cpp +++ b/base/src/refbase.cpp @@ -302,6 +302,11 @@ int RefCounter::GetWeakRefCount() return atomicWeak_.load(std::memory_order_relaxed); } +int RefCounter::GetAttemptAcquire() +{ + return atomicAttempt_.load(std::memory_order_relaxed); +} + void RefCounter::SetAttemptAcquire() { (void)atomicAttempt_.fetch_add(1, std::memory_order_relaxed); @@ -482,8 +487,17 @@ void RefBase::IncStrongRef(const void *objectId) if (curCount == INITIAL_PRIMARY_VALUE) { OnFirstStrongRef(objectId); } +} + +void RefBase::CheckIsAttemptAcquireSet(const void *objectId) +{ if (refs_->IsAttemptAcquireSet()) { refs_->ClearAttemptAcquire(); + const int attemptCount = refs_->GetAttemptAcquire(); + if (attemptCount < 0) { + UTILS_LOGF("Multi-threads trigger illegal decstrong from %{public}d due to AttemptIncStrong in ipc", + attemptCount); + } refs_->DecStrongRefCount(objectId); refs_->DecWeakRefCount(objectId); } diff --git a/base/test/benchmarktest/refbase_benchmark_test/refbase_benchmark_test.cpp b/base/test/benchmarktest/refbase_benchmark_test/refbase_benchmark_test.cpp index 15356896412e38ec39f77a577e461bd75ac8c8b1..c3032cb96d10b371a55dbf1e7899ef58c09bfe3d 100644 --- a/base/test/benchmarktest/refbase_benchmark_test/refbase_benchmark_test.cpp +++ b/base/test/benchmarktest/refbase_benchmark_test/refbase_benchmark_test.cpp @@ -349,6 +349,7 @@ int RegisterEventThread() int handle = 10; for (int i = 0; i < CYCLE_NUM2; i++) { sptr remote = ipc.FindOrNewObject(handle); + remote->CheckIsAttemptAcquireSet(remote); if (remote) { remote->IsProxyObject(); } @@ -543,10 +544,12 @@ BENCHMARK_F(BenchmarkRefbaseTest, testRefbaseOperate001)(benchmark::State& state remoteObject->AttemptAcquire(this); remoteObject->IncWeakRef(this); remoteObject->IncStrongRef(this); + remoteObject->CheckIsAttemptAcquireSet(this); remoteObject->DecStrongRef(this); remoteObject->AttemptAcquire(this); remoteObject->IncStrongRef(this); + remoteObject->CheckIsAttemptAcquireSet(this); remoteObject->DecStrongRef(this); remoteObject->DecWeakRef(this); @@ -637,6 +640,7 @@ BENCHMARK_F(BenchmarkRefbaseTest, testRefbaseAcquire001)(benchmark::State& state { AssertTrue(testobject->IsAttemptAcquireSet(), "testobject->IsAttemptAcquireSet() did not equal true", state); + testobject->CheckIsAttemptAcquireSet(this); sptr sptrRef = testobject; AssertEqual(sptrRef->GetSptrRefCount(), EXPECTED_REF_COUNT_ONE, "sptrRef->GetSptrRefCount() did not equal EXPECTED_REF_COUNT_ONE", state); diff --git a/base/test/unittest/common/utils_refbase_test.cpp b/base/test/unittest/common/utils_refbase_test.cpp index 6672314bdec350302decf2052bf36206a884e903..31a165d1c810121615cc0d6bab77bf2016aad5f6 100644 --- a/base/test/unittest/common/utils_refbase_test.cpp +++ b/base/test/unittest/common/utils_refbase_test.cpp @@ -304,6 +304,7 @@ int RegisterEventThread() int handle = 10; for (int i = 0; i < CYCLE_NUM2; i++) { sptr remote = ipc.FindOrNewObject(handle); + remote->CheckIsAttemptAcquireSet(remote); if (remote) { remote->IsProxyObject(); } @@ -348,10 +349,12 @@ HWTEST_F(UtilsRefbaseTest, testRefbaseOperateNull001, TestSize.Level0) remoteObject->IncWeakRef(nullptr); remoteObject->IncStrongRef(nullptr); + remoteObject->CheckIsAttemptAcquireSet(nullptr); remoteObject->DecStrongRef(nullptr); remoteObject->AttemptAcquire(this); remoteObject->IncStrongRef(nullptr); + remoteObject->CheckIsAttemptAcquireSet(nullptr); remoteObject->DecStrongRef(nullptr); remoteObject->DecWeakRef(nullptr); @@ -468,6 +471,7 @@ HWTEST_F(UtilsRefbaseTest, testRefbaseAcquire001, TestSize.Level0) EXPECT_EQ(testobject->GetSptrRefCount(), 1); { EXPECT_TRUE(testobject->IsAttemptAcquireSet()); + testobject->CheckIsAttemptAcquireSet(this); sptr sptrRef = testobject; EXPECT_EQ(sptrRef->GetSptrRefCount(), 1); EXPECT_FALSE(testobject->IsAttemptAcquireSet());