1e5c4badcSopenharmony_ci/*
2e5c4badcSopenharmony_ci * Copyright (C) 2021 Huawei Device Co., Ltd.
3e5c4badcSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4e5c4badcSopenharmony_ci * you may not use this file except in compliance with the License.
5e5c4badcSopenharmony_ci * You may obtain a copy of the License at
6e5c4badcSopenharmony_ci *
7e5c4badcSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8e5c4badcSopenharmony_ci *
9e5c4badcSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10e5c4badcSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11e5c4badcSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12e5c4badcSopenharmony_ci * See the License for the specific language governing permissions and
13e5c4badcSopenharmony_ci * limitations under the License.
14e5c4badcSopenharmony_ci */
15e5c4badcSopenharmony_ci
16e5c4badcSopenharmony_ci
17e5c4badcSopenharmony_ci#include "refbase.h"
18e5c4badcSopenharmony_ci
19e5c4badcSopenharmony_cinamespace OHOS {
20e5c4badcSopenharmony_ciWeakRefCounter::WeakRefCounter(RefCounter *counter, void *cookie)
21e5c4badcSopenharmony_ci    : atomicWeak_(0), refCounter_(counter), cookie_(cookie)
22e5c4badcSopenharmony_ci{
23e5c4badcSopenharmony_ci    if (refCounter_ != nullptr) {
24e5c4badcSopenharmony_ci        refCounter_->IncRefCount();
25e5c4badcSopenharmony_ci    }
26e5c4badcSopenharmony_ci}
27e5c4badcSopenharmony_ci
28e5c4badcSopenharmony_ciWeakRefCounter::~WeakRefCounter()
29e5c4badcSopenharmony_ci{
30e5c4badcSopenharmony_ci    if (refCounter_ != nullptr) {
31e5c4badcSopenharmony_ci        refCounter_->DecRefCount();
32e5c4badcSopenharmony_ci    }
33e5c4badcSopenharmony_ci}
34e5c4badcSopenharmony_ci
35e5c4badcSopenharmony_civoid* WeakRefCounter::GetRefPtr()
36e5c4badcSopenharmony_ci{
37e5c4badcSopenharmony_ci    if ((cookie_ != nullptr) && (!refCounter_->IsRefPtrValid())) {
38e5c4badcSopenharmony_ci        cookie_ = nullptr;
39e5c4badcSopenharmony_ci    }
40e5c4badcSopenharmony_ci    return cookie_;
41e5c4badcSopenharmony_ci}
42e5c4badcSopenharmony_ci
43e5c4badcSopenharmony_civoid WeakRefCounter::IncWeakRefCount(const void *objectId)
44e5c4badcSopenharmony_ci{
45e5c4badcSopenharmony_ci    if (atomicWeak_.fetch_add(1, std::memory_order_relaxed) == 0) {
46e5c4badcSopenharmony_ci        refCounter_->IncWeakRefCount(objectId);
47e5c4badcSopenharmony_ci    }
48e5c4badcSopenharmony_ci}
49e5c4badcSopenharmony_ci
50e5c4badcSopenharmony_civoid WeakRefCounter::DecWeakRefCount(const void *objectId)
51e5c4badcSopenharmony_ci{
52e5c4badcSopenharmony_ci    if (atomicWeak_.fetch_sub(1, std::memory_order_release) == 1) {
53e5c4badcSopenharmony_ci        refCounter_->DecWeakRefCount(objectId);
54e5c4badcSopenharmony_ci        delete this;
55e5c4badcSopenharmony_ci    }
56e5c4badcSopenharmony_ci}
57e5c4badcSopenharmony_ci
58e5c4badcSopenharmony_cibool WeakRefCounter::AttemptIncStrongRef(const void *objectId)
59e5c4badcSopenharmony_ci{
60e5c4badcSopenharmony_ci    int unuse = 0;
61e5c4badcSopenharmony_ci    return refCounter_->AttemptIncStrongRef(objectId, unuse);
62e5c4badcSopenharmony_ci}
63e5c4badcSopenharmony_ci
64e5c4badcSopenharmony_ciRefCounter::RefCounter()
65e5c4badcSopenharmony_ci    : atomicStrong_(INITIAL_PRIMARY_VALUE), atomicWeak_(0), atomicRefCount_(0), atomicFlags_(0), atomicAttempt_(0)
66e5c4badcSopenharmony_ci{
67e5c4badcSopenharmony_ci}
68e5c4badcSopenharmony_ciint RefCounter::GetRefCount()
69e5c4badcSopenharmony_ci{
70e5c4badcSopenharmony_ci    return atomicRefCount_.load(std::memory_order_relaxed);
71e5c4badcSopenharmony_ci}
72e5c4badcSopenharmony_ci
73e5c4badcSopenharmony_civoid RefCounter::IncRefCount()
74e5c4badcSopenharmony_ci{
75e5c4badcSopenharmony_ci    atomicRefCount_.fetch_add(1, std::memory_order_relaxed);
76e5c4badcSopenharmony_ci}
77e5c4badcSopenharmony_ci
78e5c4badcSopenharmony_civoid RefCounter::DecRefCount()
79e5c4badcSopenharmony_ci{
80e5c4badcSopenharmony_ci    if (atomicRefCount_.load(std::memory_order_relaxed) > 0) {
81e5c4badcSopenharmony_ci        if (atomicRefCount_.fetch_sub(1, std::memory_order_release) == 1) {
82e5c4badcSopenharmony_ci            delete (this);
83e5c4badcSopenharmony_ci        }
84e5c4badcSopenharmony_ci    }
85e5c4badcSopenharmony_ci}
86e5c4badcSopenharmony_ci
87e5c4badcSopenharmony_civoid RefCounter::SetCallback(const RefPtrCallback& callback)
88e5c4badcSopenharmony_ci{
89e5c4badcSopenharmony_ci    callback_ = callback;
90e5c4badcSopenharmony_ci}
91e5c4badcSopenharmony_ci
92e5c4badcSopenharmony_civoid RefCounter::RemoveCallback()
93e5c4badcSopenharmony_ci{
94e5c4badcSopenharmony_ci    callback_ = nullptr;
95e5c4badcSopenharmony_ci}
96e5c4badcSopenharmony_ci
97e5c4badcSopenharmony_cibool RefCounter::IsRefPtrValid()
98e5c4badcSopenharmony_ci{
99e5c4badcSopenharmony_ci    return callback_ != nullptr;
100e5c4badcSopenharmony_ci}
101e5c4badcSopenharmony_ci
102e5c4badcSopenharmony_ciRefCounter::~RefCounter()
103e5c4badcSopenharmony_ci{
104e5c4badcSopenharmony_ci}
105e5c4badcSopenharmony_ci
106e5c4badcSopenharmony_ciint RefCounter::IncStrongRefCount(const void * /*objectId*/)
107e5c4badcSopenharmony_ci{
108e5c4badcSopenharmony_ci    int curCount = atomicStrong_.load(std::memory_order_relaxed);
109e5c4badcSopenharmony_ci    if (curCount >= 0) {
110e5c4badcSopenharmony_ci        curCount = atomicStrong_.fetch_add(1, std::memory_order_relaxed);
111e5c4badcSopenharmony_ci        if (curCount == INITIAL_PRIMARY_VALUE) {
112e5c4badcSopenharmony_ci            atomicStrong_.fetch_sub(INITIAL_PRIMARY_VALUE, std::memory_order_release);
113e5c4badcSopenharmony_ci        }
114e5c4badcSopenharmony_ci    }
115e5c4badcSopenharmony_ci    return curCount;
116e5c4badcSopenharmony_ci}
117e5c4badcSopenharmony_ci
118e5c4badcSopenharmony_ciint RefCounter::DecStrongRefCount(const void * /*objectId*/)
119e5c4badcSopenharmony_ci{
120e5c4badcSopenharmony_ci    int curCount = GetStrongRefCount();
121e5c4badcSopenharmony_ci    if (curCount == INITIAL_PRIMARY_VALUE) {
122e5c4badcSopenharmony_ci        // unexpected case: there had never a strong reference.
123e5c4badcSopenharmony_ci    } else if (curCount > 0) {
124e5c4badcSopenharmony_ci        // we should update the current count here.
125e5c4badcSopenharmony_ci        // it may be changed after last operation.
126e5c4badcSopenharmony_ci        curCount = atomicStrong_.fetch_sub(1, std::memory_order_release);
127e5c4badcSopenharmony_ci    }
128e5c4badcSopenharmony_ci    return curCount;
129e5c4badcSopenharmony_ci}
130e5c4badcSopenharmony_ci
131e5c4badcSopenharmony_ciint RefCounter::GetStrongRefCount()
132e5c4badcSopenharmony_ci{
133e5c4badcSopenharmony_ci    return atomicStrong_.load(std::memory_order_relaxed);
134e5c4badcSopenharmony_ci}
135e5c4badcSopenharmony_ci
136e5c4badcSopenharmony_ciint RefCounter::IncWeakRefCount(const void * /*objectId*/)
137e5c4badcSopenharmony_ci{
138e5c4badcSopenharmony_ci    return atomicWeak_.fetch_add(1, std::memory_order_relaxed);
139e5c4badcSopenharmony_ci}
140e5c4badcSopenharmony_ci
141e5c4badcSopenharmony_ciint RefCounter::DecWeakRefCount(const void * /*objectId*/)
142e5c4badcSopenharmony_ci{
143e5c4badcSopenharmony_ci    int curCount = GetWeakRefCount();
144e5c4badcSopenharmony_ci    if (curCount > 0) {
145e5c4badcSopenharmony_ci        curCount = atomicWeak_.fetch_sub(1, std::memory_order_release);
146e5c4badcSopenharmony_ci    }
147e5c4badcSopenharmony_ci    int strongRefCount = GetStrongRefCount();
148e5c4badcSopenharmony_ci    if ((curCount == 1) || (strongRefCount == 0 && !IsLifeTimeExtended())) {
149e5c4badcSopenharmony_ci        if (callback_) {
150e5c4badcSopenharmony_ci            callback_();
151e5c4badcSopenharmony_ci        }
152e5c4badcSopenharmony_ci    }
153e5c4badcSopenharmony_ci    return curCount;
154e5c4badcSopenharmony_ci}
155e5c4badcSopenharmony_ci
156e5c4badcSopenharmony_ciint RefCounter::GetWeakRefCount()
157e5c4badcSopenharmony_ci{
158e5c4badcSopenharmony_ci    return atomicWeak_.load(std::memory_order_relaxed);
159e5c4badcSopenharmony_ci}
160e5c4badcSopenharmony_ci
161e5c4badcSopenharmony_civoid RefCounter::SetAttemptAcquire()
162e5c4badcSopenharmony_ci{
163e5c4badcSopenharmony_ci    (void)atomicAttempt_.fetch_add(1, std::memory_order_relaxed);
164e5c4badcSopenharmony_ci}
165e5c4badcSopenharmony_ci
166e5c4badcSopenharmony_cibool RefCounter::IsAttemptAcquireSet()
167e5c4badcSopenharmony_ci{
168e5c4badcSopenharmony_ci    return static_cast<bool>(atomicAttempt_.load(std::memory_order_relaxed) > 0);
169e5c4badcSopenharmony_ci}
170e5c4badcSopenharmony_ci
171e5c4badcSopenharmony_civoid RefCounter::ClearAttemptAcquire()
172e5c4badcSopenharmony_ci{
173e5c4badcSopenharmony_ci    atomicAttempt_.fetch_sub(1, std::memory_order_relaxed);
174e5c4badcSopenharmony_ci}
175e5c4badcSopenharmony_ci
176e5c4badcSopenharmony_civoid RefCounter::ExtendObjectLifetime()
177e5c4badcSopenharmony_ci{
178e5c4badcSopenharmony_ci    atomicFlags_.fetch_or(FLAG_EXTEND_LIFE_TIME, std::memory_order_relaxed);
179e5c4badcSopenharmony_ci}
180e5c4badcSopenharmony_ci
181e5c4badcSopenharmony_cibool RefCounter::IsLifeTimeExtended()
182e5c4badcSopenharmony_ci{
183e5c4badcSopenharmony_ci    return static_cast<bool>(atomicFlags_.load(std::memory_order_relaxed) & FLAG_EXTEND_LIFE_TIME);
184e5c4badcSopenharmony_ci}
185e5c4badcSopenharmony_ci
186e5c4badcSopenharmony_cibool RefCounter::AttemptIncStrongRef(const void *objectId, int &outCount)
187e5c4badcSopenharmony_ci{
188e5c4badcSopenharmony_ci    int curCount = GetStrongRefCount();
189e5c4badcSopenharmony_ci    IncWeakRefCount(objectId);
190e5c4badcSopenharmony_ci
191e5c4badcSopenharmony_ci    // if the object already had strong references.just promoting it.
192e5c4badcSopenharmony_ci    while ((curCount > 0) && (curCount != INITIAL_PRIMARY_VALUE)) {
193e5c4badcSopenharmony_ci        if (atomicStrong_.compare_exchange_weak(curCount, curCount + 1, std::memory_order_relaxed)) {
194e5c4badcSopenharmony_ci            goto attempt_success;
195e5c4badcSopenharmony_ci        }
196e5c4badcSopenharmony_ci
197e5c4badcSopenharmony_ci        // someone else changed the counter.re-acquire the counter value.
198e5c4badcSopenharmony_ci        curCount = atomicStrong_.load(std::memory_order_relaxed);
199e5c4badcSopenharmony_ci    }
200e5c4badcSopenharmony_ci
201e5c4badcSopenharmony_ci    if ((curCount == INITIAL_PRIMARY_VALUE) && !IsLifeTimeExtended()) {
202e5c4badcSopenharmony_ci        // this object has a "normal" life-time,
203e5c4badcSopenharmony_ci        while (curCount > 0) {
204e5c4badcSopenharmony_ci            if (atomicStrong_.compare_exchange_weak(curCount, curCount + 1, std::memory_order_relaxed)) {
205e5c4badcSopenharmony_ci                goto attempt_success;
206e5c4badcSopenharmony_ci            }
207e5c4badcSopenharmony_ci
208e5c4badcSopenharmony_ci            curCount = atomicStrong_.load(std::memory_order_relaxed);
209e5c4badcSopenharmony_ci        }
210e5c4badcSopenharmony_ci    }
211e5c4badcSopenharmony_ci
212e5c4badcSopenharmony_ci    if (IsLifeTimeExtended()) {
213e5c4badcSopenharmony_ci        curCount = atomicStrong_.fetch_add(1, std::memory_order_relaxed);
214e5c4badcSopenharmony_ci    }
215e5c4badcSopenharmony_ci
216e5c4badcSopenharmony_ciattempt_success:
217e5c4badcSopenharmony_ci    if (curCount >= INITIAL_PRIMARY_VALUE) {
218e5c4badcSopenharmony_ci        outCount = curCount;
219e5c4badcSopenharmony_ci        atomicStrong_.fetch_sub(INITIAL_PRIMARY_VALUE, std::memory_order_release);
220e5c4badcSopenharmony_ci        return true;
221e5c4badcSopenharmony_ci    }
222e5c4badcSopenharmony_ci
223e5c4badcSopenharmony_ci    if (curCount < 0 || (!IsLifeTimeExtended() && curCount == 0)) {
224e5c4badcSopenharmony_ci        // the object destroyed on strong reference count reduce to zero.
225e5c4badcSopenharmony_ci        DecWeakRefCount(objectId);
226e5c4badcSopenharmony_ci        return false;
227e5c4badcSopenharmony_ci    }
228e5c4badcSopenharmony_ci    return true;
229e5c4badcSopenharmony_ci}
230e5c4badcSopenharmony_ci
231e5c4badcSopenharmony_ciRefBase::RefBase() : refs_(new RefCounter())
232e5c4badcSopenharmony_ci{
233e5c4badcSopenharmony_ci    refs_->IncRefCount();
234e5c4badcSopenharmony_ci    refs_->SetCallback([this] {
235e5c4badcSopenharmony_ci        this->RefPtrCallback();
236e5c4badcSopenharmony_ci    });
237e5c4badcSopenharmony_ci}
238e5c4badcSopenharmony_ci
239e5c4badcSopenharmony_ciRefBase::RefBase(const RefBase& /*other*/)
240e5c4badcSopenharmony_ci{
241e5c4badcSopenharmony_ci    refs_ = new RefCounter();
242e5c4badcSopenharmony_ci    if (refs_ != nullptr) {
243e5c4badcSopenharmony_ci        refs_->IncRefCount();
244e5c4badcSopenharmony_ci        refs_->SetCallback([this] {
245e5c4badcSopenharmony_ci            this->RefPtrCallback();
246e5c4badcSopenharmony_ci        });
247e5c4badcSopenharmony_ci    }
248e5c4badcSopenharmony_ci}
249e5c4badcSopenharmony_ci
250e5c4badcSopenharmony_civoid RefBase::RefPtrCallback()
251e5c4badcSopenharmony_ci{
252e5c4badcSopenharmony_ci    delete this;
253e5c4badcSopenharmony_ci}
254e5c4badcSopenharmony_ci
255e5c4badcSopenharmony_ci/*
256e5c4badcSopenharmony_ci * The two ends of the assignment are two independent and exclusive,
257e5c4badcSopenharmony_ci * and the application should not share the reference counter.
258e5c4badcSopenharmony_ci * RISK: If there is a reference count on the left of the equal sign,
259e5c4badcSopenharmony_ci * it may cause a reference count exception
260e5c4badcSopenharmony_ci */
261e5c4badcSopenharmony_ciRefBase &RefBase::operator=(const RefBase& /*other*/)
262e5c4badcSopenharmony_ci{
263e5c4badcSopenharmony_ci    if (refs_ != nullptr) {
264e5c4badcSopenharmony_ci        refs_->RemoveCallback();
265e5c4badcSopenharmony_ci        refs_->DecRefCount();
266e5c4badcSopenharmony_ci    }
267e5c4badcSopenharmony_ci    refs_ = new RefCounter();
268e5c4badcSopenharmony_ci    if (refs_ != nullptr) {
269e5c4badcSopenharmony_ci        refs_->IncRefCount();
270e5c4badcSopenharmony_ci        refs_->SetCallback([this] {
271e5c4badcSopenharmony_ci            this->RefPtrCallback();
272e5c4badcSopenharmony_ci        });
273e5c4badcSopenharmony_ci    }
274e5c4badcSopenharmony_ci    return *this;
275e5c4badcSopenharmony_ci}
276e5c4badcSopenharmony_ci
277e5c4badcSopenharmony_ciRefBase::RefBase(RefBase &&other) noexcept
278e5c4badcSopenharmony_ci{
279e5c4badcSopenharmony_ci    refs_ = other.refs_;
280e5c4badcSopenharmony_ci    other.refs_ = nullptr;
281e5c4badcSopenharmony_ci}
282e5c4badcSopenharmony_ci
283e5c4badcSopenharmony_ciRefBase &RefBase::operator=(RefBase &&other)  noexcept
284e5c4badcSopenharmony_ci{
285e5c4badcSopenharmony_ci    if (refs_ == other.refs_) {
286e5c4badcSopenharmony_ci        return *this;
287e5c4badcSopenharmony_ci    }
288e5c4badcSopenharmony_ci    if (refs_ != nullptr) {
289e5c4badcSopenharmony_ci        refs_->RemoveCallback();
290e5c4badcSopenharmony_ci        refs_->DecRefCount();
291e5c4badcSopenharmony_ci    }
292e5c4badcSopenharmony_ci    refs_ = other.refs_;
293e5c4badcSopenharmony_ci    other.refs_ = nullptr;
294e5c4badcSopenharmony_ci    return *this;
295e5c4badcSopenharmony_ci}
296e5c4badcSopenharmony_ci
297e5c4badcSopenharmony_ciRefBase::~RefBase()
298e5c4badcSopenharmony_ci{
299e5c4badcSopenharmony_ci    if (refs_ != nullptr) {
300e5c4badcSopenharmony_ci        refs_->RemoveCallback();
301e5c4badcSopenharmony_ci        refs_->DecRefCount();
302e5c4badcSopenharmony_ci        refs_ = nullptr;
303e5c4badcSopenharmony_ci    }
304e5c4badcSopenharmony_ci}
305e5c4badcSopenharmony_ci
306e5c4badcSopenharmony_civoid RefBase::ExtendObjectLifetime()
307e5c4badcSopenharmony_ci{
308e5c4badcSopenharmony_ci    refs_->ExtendObjectLifetime();
309e5c4badcSopenharmony_ci}
310e5c4badcSopenharmony_ci
311e5c4badcSopenharmony_civoid RefBase::IncStrongRef(const void *objectId)
312e5c4badcSopenharmony_ci{
313e5c4badcSopenharmony_ci    if (refs_ == nullptr) {
314e5c4badcSopenharmony_ci        return;
315e5c4badcSopenharmony_ci    }
316e5c4badcSopenharmony_ci    const int curCount = refs_->IncStrongRefCount(objectId);
317e5c4badcSopenharmony_ci    IncWeakRef(objectId);
318e5c4badcSopenharmony_ci    if (curCount == INITIAL_PRIMARY_VALUE) {
319e5c4badcSopenharmony_ci        OnFirstStrongRef(objectId);
320e5c4badcSopenharmony_ci    }
321e5c4badcSopenharmony_ci    if (refs_->IsAttemptAcquireSet()) {
322e5c4badcSopenharmony_ci        refs_->ClearAttemptAcquire();
323e5c4badcSopenharmony_ci        refs_->DecStrongRefCount(objectId);
324e5c4badcSopenharmony_ci    }
325e5c4badcSopenharmony_ci}
326e5c4badcSopenharmony_ci
327e5c4badcSopenharmony_civoid RefBase::DecStrongRef(const void *objectId)
328e5c4badcSopenharmony_ci{
329e5c4badcSopenharmony_ci    if (refs_ == nullptr) {
330e5c4badcSopenharmony_ci        return;
331e5c4badcSopenharmony_ci    }
332e5c4badcSopenharmony_ci    const int curCount = refs_->DecStrongRefCount(objectId);
333e5c4badcSopenharmony_ci    if (curCount == 1) {
334e5c4badcSopenharmony_ci        OnLastStrongRef(objectId);
335e5c4badcSopenharmony_ci    }
336e5c4badcSopenharmony_ci    DecWeakRef(objectId);
337e5c4badcSopenharmony_ci}
338e5c4badcSopenharmony_ci
339e5c4badcSopenharmony_ciint RefBase::GetSptrRefCount()
340e5c4badcSopenharmony_ci{
341e5c4badcSopenharmony_ci    if (refs_ != nullptr) {
342e5c4badcSopenharmony_ci        return refs_->GetStrongRefCount();
343e5c4badcSopenharmony_ci    } else {
344e5c4badcSopenharmony_ci        return 0;
345e5c4badcSopenharmony_ci    }
346e5c4badcSopenharmony_ci}
347e5c4badcSopenharmony_ci
348e5c4badcSopenharmony_ciWeakRefCounter *RefBase::CreateWeakRef(void *cookie)
349e5c4badcSopenharmony_ci{
350e5c4badcSopenharmony_ci    if (refs_ != nullptr) {
351e5c4badcSopenharmony_ci        return new WeakRefCounter(refs_, cookie);
352e5c4badcSopenharmony_ci    }
353e5c4badcSopenharmony_ci
354e5c4badcSopenharmony_ci    return nullptr;
355e5c4badcSopenharmony_ci}
356e5c4badcSopenharmony_ci
357e5c4badcSopenharmony_civoid RefBase::IncWeakRef(const void *objectId)
358e5c4badcSopenharmony_ci{
359e5c4badcSopenharmony_ci    if (refs_ != nullptr) {
360e5c4badcSopenharmony_ci        refs_->IncWeakRefCount(objectId);
361e5c4badcSopenharmony_ci    }
362e5c4badcSopenharmony_ci}
363e5c4badcSopenharmony_ci
364e5c4badcSopenharmony_civoid RefBase::DecWeakRef(const void *objectId)
365e5c4badcSopenharmony_ci{
366e5c4badcSopenharmony_ci    if (refs_ != nullptr) {
367e5c4badcSopenharmony_ci        refs_->DecWeakRefCount(objectId);
368e5c4badcSopenharmony_ci    }
369e5c4badcSopenharmony_ci}
370e5c4badcSopenharmony_ci
371e5c4badcSopenharmony_ciint RefBase::GetWptrRefCount()
372e5c4badcSopenharmony_ci{
373e5c4badcSopenharmony_ci    if (refs_ != nullptr) {
374e5c4badcSopenharmony_ci        return refs_->GetWeakRefCount();
375e5c4badcSopenharmony_ci    } else {
376e5c4badcSopenharmony_ci        return 0;
377e5c4badcSopenharmony_ci    }
378e5c4badcSopenharmony_ci}
379e5c4badcSopenharmony_ci
380e5c4badcSopenharmony_cibool RefBase::AttemptAcquire(const void *objectId)
381e5c4badcSopenharmony_ci{
382e5c4badcSopenharmony_ci    if (refs_ != nullptr) {
383e5c4badcSopenharmony_ci        int count = 0;
384e5c4badcSopenharmony_ci        if (refs_->AttemptIncStrongRef(objectId, count)) {
385e5c4badcSopenharmony_ci            if (count == INITIAL_PRIMARY_VALUE) {
386e5c4badcSopenharmony_ci                OnFirstStrongRef(objectId);
387e5c4badcSopenharmony_ci            }
388e5c4badcSopenharmony_ci            refs_->SetAttemptAcquire();
389e5c4badcSopenharmony_ci            return true;
390e5c4badcSopenharmony_ci        }
391e5c4badcSopenharmony_ci    }
392e5c4badcSopenharmony_ci    return false;
393e5c4badcSopenharmony_ci}
394e5c4badcSopenharmony_ci
395e5c4badcSopenharmony_cibool RefBase::AttemptIncStrongRef(const void *objectId)
396e5c4badcSopenharmony_ci{
397e5c4badcSopenharmony_ci    if ((refs_ != nullptr) && (OnAttemptPromoted(objectId))) {
398e5c4badcSopenharmony_ci        int count = 0;
399e5c4badcSopenharmony_ci        bool ret = refs_->AttemptIncStrongRef(objectId, count);
400e5c4badcSopenharmony_ci        if (count == INITIAL_PRIMARY_VALUE) {
401e5c4badcSopenharmony_ci            OnFirstStrongRef(objectId);
402e5c4badcSopenharmony_ci        }
403e5c4badcSopenharmony_ci        return ret;
404e5c4badcSopenharmony_ci    }
405e5c4badcSopenharmony_ci    return false;
406e5c4badcSopenharmony_ci}
407e5c4badcSopenharmony_ci
408e5c4badcSopenharmony_cibool RefBase::IsAttemptAcquireSet()
409e5c4badcSopenharmony_ci{
410e5c4badcSopenharmony_ci    if (refs_ != nullptr) {
411e5c4badcSopenharmony_ci        return refs_->IsAttemptAcquireSet();
412e5c4badcSopenharmony_ci    }
413e5c4badcSopenharmony_ci    return false;
414e5c4badcSopenharmony_ci}
415e5c4badcSopenharmony_ci
416e5c4badcSopenharmony_cibool RefBase::IsExtendLifeTimeSet()
417e5c4badcSopenharmony_ci{
418e5c4badcSopenharmony_ci    if (refs_ != nullptr) {
419e5c4badcSopenharmony_ci        return refs_->IsLifeTimeExtended();
420e5c4badcSopenharmony_ci    }
421e5c4badcSopenharmony_ci    return false;
422e5c4badcSopenharmony_ci}
423e5c4badcSopenharmony_ci
424e5c4badcSopenharmony_civoid RefBase::OnFirstStrongRef(const void *)
425e5c4badcSopenharmony_ci{}
426e5c4badcSopenharmony_ci
427e5c4badcSopenharmony_civoid RefBase::OnLastStrongRef(const void *)
428e5c4badcSopenharmony_ci{}
429e5c4badcSopenharmony_ci
430e5c4badcSopenharmony_civoid RefBase::OnLastWeakRef(const void *)
431e5c4badcSopenharmony_ci{}
432e5c4badcSopenharmony_ci
433e5c4badcSopenharmony_cibool RefBase::OnAttemptPromoted(const void *)
434e5c4badcSopenharmony_ci{
435e5c4badcSopenharmony_ci    return true;
436e5c4badcSopenharmony_ci}
437e5c4badcSopenharmony_ci} // namespace OHOS
438