• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "refbase.h"
17 #include "utils_log.h"
18 #ifdef DEBUG_REFBASE
19 #include <unistd.h>
20 #endif
21 
22 namespace OHOS {
23 
RefBaseDebugPrint(int curCount,const void * caller,const void * objectId,const char * operation,const char * countType)24 void RefCounter::RefBaseDebugPrint([[maybe_unused]] int curCount,
25     [[maybe_unused]] const void* caller,
26     [[maybe_unused]] const void* objectId,
27     [[maybe_unused]] const char* operation,
28     [[maybe_unused]] const char* countType)
29 {
30 #if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE))
31     if (this->enableTrack) {
32         UTILS_LOGT(this->domainId_, "curCount: %{public}d, operation: %{public}s, countType: %{public}s",
33             curCount, operation, countType);
34     }
35 #endif
36 }
37 
WeakRefCounter(RefCounter * counter,void * cookie)38 WeakRefCounter::WeakRefCounter(RefCounter *counter, void *cookie)
39     : atomicWeak_(0), refCounter_(counter), cookie_(cookie)
40 {
41     if (refCounter_ != nullptr) {
42         refCounter_->IncRefCount();
43     }
44 }
45 
~WeakRefCounter()46 WeakRefCounter::~WeakRefCounter()
47 {
48     if (refCounter_ != nullptr) {
49         refCounter_->DecRefCount();
50     }
51 }
52 
GetWeakRefCount() const53 int WeakRefCounter::GetWeakRefCount() const
54 {
55     return atomicWeak_.load(std::memory_order_relaxed);
56 }
57 
GetRefPtr()58 void* WeakRefCounter::GetRefPtr()
59 {
60     if ((cookie_ != nullptr) && (!refCounter_->IsRefPtrValid())) {
61         cookie_ = nullptr;
62     }
63     return cookie_;
64 }
65 
IncWeakRefCount(const void * objectId)66 void WeakRefCounter::IncWeakRefCount(const void *objectId)
67 {
68     if (atomicWeak_.fetch_add(1, std::memory_order_relaxed) == 0) {
69         refCounter_->IncWeakRefCount(objectId);
70     }
71 }
72 
DecWeakRefCount(const void * objectId)73 void WeakRefCounter::DecWeakRefCount(const void *objectId)
74 {
75     if (atomicWeak_.fetch_sub(1, std::memory_order_release) == 1) {
76         refCounter_->DecWeakRefCount(objectId);
77         delete this;
78     }
79 }
80 
AttemptIncStrongRef(const void * objectId)81 bool WeakRefCounter::AttemptIncStrongRef(const void *objectId)
82 {
83     int unuse = 0;
84     return refCounter_->AttemptIncStrongRef(objectId, unuse);
85 }
86 
87 #if ((defined DEBUG_REFBASE) && (!defined PRINT_TRACK_AT_ONCE))
88 // RefTracker is a debug tool, used to record the trace of RefBase.
89 // RefTracker will save the information about the count of RefBase,
90 // including the pointer of sptr/wptr(The pointer of itself, not the pointer
91 // it manages), the amount of strong/weak/refcout and the PID&TID.
92 // The Tracker can live with RefCounter.
93 // User should keep thread-safety of RefTracker.
94 class RefTracker {
95 public:
96     RefTracker(RefTracker* exTracker, const void* id, int strong, int weak, int ref, int pid, int tid);
97 
98     void PrintTrace(const void* refCounterPtr);
99 
100     RefTracker* PopTrace(const void* refCounterPtr);
101 
102 private:
103     const void* ptrID;
104     int strongRefCnt;
105     int weakRefCnt;
106     int refCnt;
107     int PID;
108     int TID;
109     RefTracker* exTrace;
110 };
111 
RefTracker(RefTracker * exTracker,const void * id,int strong,int weak,int ref,int pid,int tid)112 RefTracker::RefTracker(RefTracker* exTracker, const void* id, int strong, int weak, int ref, int pid, int tid)
113     : ptrID (id), strongRefCnt (strong), weakRefCnt (weak), refCnt (ref), PID (pid), TID (tid), exTrace (exTracker)
114 {
115 }
116 
PrintTrace(const void * refCounterPtr)117 void RefTracker::PrintTrace(const void* refCounterPtr)
118 {
119     UTILS_LOGI("strong: %{public}d weak: %{public}d, refcnt: %{public}d PID: %{public}d TID: %{public}d",
120         strongRefCnt, weakRefCnt, refCnt, PID, TID);
121 }
122 
PopTrace(const void * refCounterPtr)123 RefTracker* RefTracker::PopTrace(const void* refCounterPtr)
124 {
125     RefTracker* ref = exTrace;
126     PrintTrace(refCounterPtr);
127     delete this;
128     return ref;
129 }
130 #endif
131 
132 #ifdef DEBUG_REFBASE
133 #ifdef PRINT_TRACK_AT_ONCE
EnableTrackerWithDomainId(unsigned int domainId)134 void RefCounter::EnableTrackerWithDomainId(unsigned int domainId)
135 {
136     std::lock_guard<std::mutex> lock(trackerMutex);
137     this->domainId_ = domainId;
138     enableTrack = true;
139 }
140 #else
GetNewTrace(const void * objectId)141 void RefCounter::GetNewTrace(const void* objectId)
142 {
143     std::lock_guard<std::mutex> lock(trackerMutex);
144     RefTracker* newTracker = new RefTracker(refTracker, objectId, atomicStrong_,
145         atomicWeak_, atomicRefCount_, getpid(), gettid());
146     refTracker = newTracker;
147 }
148 
PrintTracker()149 void RefCounter::PrintTracker()
150 {
151     std::lock_guard<std::mutex> lock(trackerMutex);
152     if (refTracker) {
153         UTILS_LOGI("Start backtrace");
154         while (refTracker) {
155             refTracker = refTracker->PopTrace(this);
156         }
157         UTILS_LOGI("End backtrace");
158     }
159 }
160 #endif
161 
162 #ifndef TRACK_ALL
EnableTracker()163 void RefCounter::EnableTracker()
164 {
165     std::lock_guard<std::mutex> lock(trackerMutex);
166 #ifndef PRINT_TRACK_AT_ONCE
167     enableTrack = true;
168 #endif
169 }
170 #endif
171 
172 #endif
173 
DebugRefBase(const void * objectId)174 void RefCounter::DebugRefBase([[maybe_unused]]const void* objectId)
175 {
176 #ifdef DEBUG_REFBASE
177     if (enableTrack) {
178 #ifndef PRINT_TRACK_AT_ONCE
179         GetNewTrace(objectId);
180 #endif
181     }
182 #endif
183 }
184 
RefCounter()185 RefCounter::RefCounter()
186     : atomicStrong_(INITIAL_PRIMARY_VALUE), atomicWeak_(0), atomicRefCount_(0), atomicFlags_(0), atomicAttempt_(0)
187 {
188 }
189 
GetRefCount()190 int RefCounter::GetRefCount()
191 {
192     return atomicRefCount_.load(std::memory_order_relaxed);
193 }
194 
IncRefCount()195 void RefCounter::IncRefCount()
196 {
197 #if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE))
198     int curCount = atomicRefCount_.fetch_add(1, std::memory_order_relaxed);
199     RefBaseDebugPrint(curCount, __builtin_return_address(0), nullptr, "++", "atomicRefCount_");
200 #else
201     atomicRefCount_.fetch_add(1, std::memory_order_relaxed);
202 #endif
203 }
204 
DecRefCount()205 void RefCounter::DecRefCount()
206 {
207     if (atomicRefCount_.load(std::memory_order_relaxed) > 0) {
208         int curCount = atomicRefCount_.fetch_sub(1, std::memory_order_release);
209 #if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE))
210         RefBaseDebugPrint(curCount, __builtin_return_address(0), nullptr, "++", "atomicRefCount_");
211 #endif
212         if (curCount == 1) {
213             delete (this);
214         }
215     }
216 }
217 
SetCallback(const RefPtrCallback & callback)218 void RefCounter::SetCallback(const RefPtrCallback& callback)
219 {
220     callback_ = callback;
221 }
222 
RemoveCallback()223 void RefCounter::RemoveCallback()
224 {
225     callback_ = nullptr;
226 }
227 
IsRefPtrValid()228 bool RefCounter::IsRefPtrValid()
229 {
230     return callback_ != nullptr;
231 }
232 
233 #ifdef OHOS_PLATFORM
SetCanPromote(const CanPromote & canPromote)234 void RefCounter::SetCanPromote(const CanPromote &canPromote)
235 {
236     canPromote_ = canPromote;
237 }
238 
RemoveCanPromote()239 void RefCounter::RemoveCanPromote()
240 {
241     canPromote_ = nullptr;
242 }
243 
IsCanPromoteValid()244 bool RefCounter::IsCanPromoteValid()
245 {
246     return canPromote_ != nullptr;
247 }
248 #endif
249 
~RefCounter()250 RefCounter::~RefCounter()
251 {
252 #ifdef DEBUG_REFBASE
253     if (enableTrack) {
254 #ifndef PRINT_TRACK_AT_ONCE
255         PrintTracker();
256 #endif
257     }
258 #endif
259 }
260 
IncStrongRefCount(const void * objectId)261 int RefCounter::IncStrongRefCount(const void* objectId)
262 {
263     DebugRefBase(objectId);
264     int curCount = atomicStrong_.load(std::memory_order_relaxed);
265     if (curCount >= 0) {
266         curCount = atomicStrong_.fetch_add(1, std::memory_order_relaxed);
267 #if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE))
268         RefBaseDebugPrint(curCount, __builtin_return_address(0), objectId, "++", "atomicStrong_");
269 #endif
270         if (curCount == INITIAL_PRIMARY_VALUE) {
271 #if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE))
272             int newCurCount = atomicStrong_.fetch_sub(INITIAL_PRIMARY_VALUE, std::memory_order_release);
273             RefBaseDebugPrint(newCurCount, __builtin_return_address(0), objectId, "--", "atomicStrong_");
274 #else
275             atomicStrong_.fetch_sub(INITIAL_PRIMARY_VALUE, std::memory_order_release);
276 #endif
277         }
278     }
279 
280     return curCount;
281 }
282 
DecStrongRefCount(const void * objectId)283 int RefCounter::DecStrongRefCount(const void* objectId)
284 {
285     DebugRefBase(objectId);
286     int curCount = GetStrongRefCount();
287     if (curCount == INITIAL_PRIMARY_VALUE) {
288         // unexpected case: there had never a strong reference.
289         UTILS_LOGD("decStrongRef when there is nerver a strong reference");
290     } else if (curCount > 0) {
291         // we should update the current count here.
292         // it may be changed after last operation.
293         curCount = atomicStrong_.fetch_sub(1, std::memory_order_release);
294 #if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE))
295         RefBaseDebugPrint(curCount, __builtin_return_address(0), objectId, "--", "atomicStrong_");
296 #endif
297     }
298 
299     return curCount;
300 }
301 
GetStrongRefCount()302 int RefCounter::GetStrongRefCount()
303 {
304     return atomicStrong_.load(std::memory_order_relaxed);
305 }
306 
IncWeakRefCount(const void * objectId)307 int RefCounter::IncWeakRefCount(const void* objectId)
308 {
309     DebugRefBase(objectId);
310     int curCount = atomicWeak_.fetch_add(1, std::memory_order_relaxed);
311 #if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE))
312     RefBaseDebugPrint(curCount, __builtin_return_address(0), objectId, "++", "atomicWeak_");
313 #endif
314     return curCount;
315 }
316 
DecWeakRefCount(const void * objectId)317 int RefCounter::DecWeakRefCount(const void* objectId)
318 {
319     DebugRefBase(objectId);
320     int curCount = GetWeakRefCount();
321     if (curCount > 0) {
322         curCount = atomicWeak_.fetch_sub(1, std::memory_order_release);
323 #if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE))
324         RefBaseDebugPrint(curCount, __builtin_return_address(0), objectId, "--", "atomicWeak_");
325 #endif
326     }
327 
328     if (curCount != 1) {
329         return curCount;
330     }
331     std::atomic_thread_fence(std::memory_order_acquire);
332     if (IsLifeTimeExtended()) {
333         if (callback_) {
334             callback_();
335         }
336     } else {
337         // only weak ptr but never had a strong ref, we should do nothing here theoretically. But it may cause a leak.
338         if (GetStrongRefCount() == INITIAL_PRIMARY_VALUE) {
339             UTILS_LOGW("dec the last weakRef before it had a strong reference, delete refbase to avoid Memory Leak");
340             if (callback_) {
341                 callback_();
342             }
343         } else {
344             // free RefCounter
345             DecRefCount();
346         }
347     }
348 
349     return curCount;
350 }
351 
GetWeakRefCount()352 int RefCounter::GetWeakRefCount()
353 {
354     return atomicWeak_.load(std::memory_order_relaxed);
355 }
356 
GetAttemptAcquire()357 int RefCounter::GetAttemptAcquire()
358 {
359     return atomicAttempt_.load(std::memory_order_relaxed);
360 }
361 
SetAttemptAcquire()362 void RefCounter::SetAttemptAcquire()
363 {
364 #if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE))
365     int curCount = atomicAttempt_.fetch_add(1, std::memory_order_relaxed);
366     RefBaseDebugPrint(curCount, __builtin_return_address(0), nullptr, "++", "atomicAttempt_");
367 #else
368     (void)atomicAttempt_.fetch_add(1, std::memory_order_relaxed);
369 #endif
370 }
371 
IsAttemptAcquireSet()372 bool RefCounter::IsAttemptAcquireSet()
373 {
374     return static_cast<bool>(atomicAttempt_.load(std::memory_order_relaxed) > 0);
375 }
376 
ClearAttemptAcquire()377 void RefCounter::ClearAttemptAcquire()
378 {
379 #if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE))
380     int curCount = atomicAttempt_.fetch_sub(1, std::memory_order_relaxed);
381     RefBaseDebugPrint(curCount, __builtin_return_address(0), nullptr, "--", "atomicAttempt_");
382 #else
383     atomicAttempt_.fetch_sub(1, std::memory_order_relaxed);
384 #endif
385 }
386 
ExtendObjectLifetime()387 void RefCounter::ExtendObjectLifetime()
388 {
389     atomicFlags_.fetch_or(FLAG_EXTEND_LIFE_TIME, std::memory_order_relaxed);
390 }
391 
IsLifeTimeExtended()392 bool RefCounter::IsLifeTimeExtended()
393 {
394     return static_cast<bool>(atomicFlags_.load(std::memory_order_relaxed) & FLAG_EXTEND_LIFE_TIME);
395 }
396 
AttemptIncStrongRef(const void * objectId,int & outCount)397 bool RefCounter::AttemptIncStrongRef(const void *objectId, int &outCount)
398 {
399     int curCount = GetStrongRefCount();
400     IncWeakRefCount(objectId);
401 
402     // if the object already had strong references.just promoting it.
403     while ((curCount > 0) && (curCount != INITIAL_PRIMARY_VALUE)) {
404         if (atomicStrong_.compare_exchange_weak(curCount, curCount + 1, std::memory_order_relaxed)) {
405             RefBaseDebugPrint(curCount, __builtin_return_address(0), objectId, "++", "atomicStrong_");
406             goto ATTEMPT_SUCCESS;
407         }
408         // someone else changed the counter.re-acquire the counter value.
409         curCount = atomicStrong_.load(std::memory_order_relaxed);
410     }
411 
412     if ((curCount == INITIAL_PRIMARY_VALUE) && !IsLifeTimeExtended()) {
413         // this object has a "normal" life-time,
414         while (curCount > 0) {
415             if (atomicStrong_.compare_exchange_weak(curCount, curCount + 1, std::memory_order_relaxed)) {
416                 RefBaseDebugPrint(curCount, __builtin_return_address(0), objectId, "++", "atomicStrong_");
417                 goto ATTEMPT_SUCCESS;
418             }
419             curCount = atomicStrong_.load(std::memory_order_relaxed);
420         }
421     }
422 
423     if (IsLifeTimeExtended()) {
424 #ifdef OHOS_PLATFORM
425         if (!IsCanPromoteValid() || !canPromote_()) {
426             return false;
427         }
428 #endif
429         curCount = atomicStrong_.fetch_add(1, std::memory_order_relaxed);
430         RefBaseDebugPrint(curCount, __builtin_return_address(0), objectId, "++", "atomicStrong_");
431     }
432 
433 ATTEMPT_SUCCESS:
434     if (curCount == INITIAL_PRIMARY_VALUE) {
435         outCount = curCount;
436 #if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE))
437         int newCurCount = atomicStrong_.fetch_sub(INITIAL_PRIMARY_VALUE, std::memory_order_release);
438         RefBaseDebugPrint(newCurCount, __builtin_return_address(0), objectId, "--", "atomicStrong_");
439 #else
440         atomicStrong_.fetch_sub(INITIAL_PRIMARY_VALUE, std::memory_order_release);
441 #endif
442         return true;
443     }
444 
445     if (curCount < 0 || (!IsLifeTimeExtended() && curCount == 0)) {
446         // the object destroyed on strong reference count reduce to zero.
447         DecWeakRefCount(objectId);
448         return false;
449     }
450 
451     return true;
452 }
453 
AttemptIncStrong(const void * objectId)454 bool RefCounter::AttemptIncStrong(const void *objectId)
455 {
456     IncWeakRefCount(objectId);
457     int curCount = GetStrongRefCount();
458     while (curCount > 0) {
459         if (atomicStrong_.compare_exchange_weak(curCount, curCount + 1, std::memory_order_relaxed)) {
460 #if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE))
461             RefBaseDebugPrint(curCount, __builtin_return_address(0), objectId, "++", "atomicStrong_");
462 #endif
463             break;
464         }
465         // curCount has been updated.
466     }
467     if (curCount <= 0) {
468         DecWeakRefCount(objectId);
469     }
470     return curCount > 0;
471 }
472 
RefBase()473 RefBase::RefBase() : refs_(new RefCounter())
474 {
475     refs_->IncRefCount();
476     refs_->SetCallback([this] { this->RefPtrCallback(); });
477 #ifdef OHOS_PLATFORM
478     refs_->SetCanPromote([this] { return this->CanPromote(); });
479 #endif
480 }
481 
RefBase(const RefBase &)482 RefBase::RefBase(const RefBase &)
483 {
484     refs_ = new (std::nothrow) RefCounter();
485     if (refs_ != nullptr) {
486         refs_->IncRefCount();
487         refs_->SetCallback([this] { this->RefPtrCallback(); });
488 #ifdef OHOS_PLATFORM
489         refs_->SetCanPromote([this] { return this->CanPromote(); });
490 #endif
491     }
492 }
493 
494 #ifdef OHOS_PLATFORM
CanPromote()495 bool RefBase::CanPromote()
496 {
497     return true;
498 }
499 #endif
500 
RefPtrCallback()501 void RefBase::RefPtrCallback()
502 {
503     delete this;
504 }
505 
506 /*
507  * The two ends of the assignment are two independent and exclusive,
508  * and the application should not share the reference counter.
509  * RISK: If there is a reference count on the left of the equal sign,
510  * it may cause a reference count exception
511  */
operator =(const RefBase &)512 RefBase &RefBase::operator=(const RefBase &)
513 {
514     if (refs_ != nullptr) {
515         refs_->RemoveCallback();
516         refs_->DecRefCount();
517     }
518 
519     refs_ = new (std::nothrow) RefCounter();
520     if (refs_ != nullptr) {
521         refs_->IncRefCount();
522         refs_->SetCallback([this] { this->RefPtrCallback(); });
523 #ifdef OHOS_PLATFORM
524         refs_->SetCanPromote([this] { return this->CanPromote(); });
525 #endif
526     }
527 
528     return *this;
529 }
530 
RefBase(RefBase && other)531 RefBase::RefBase(RefBase &&other) noexcept
532 {
533     refs_ = other.refs_;
534     other.refs_ = nullptr;
535 }
536 
operator =(RefBase && other)537 RefBase &RefBase::operator=(RefBase &&other) noexcept
538 {
539     if (refs_ == other.refs_) {
540         return *this;
541     }
542 
543     if (refs_ != nullptr) {
544         refs_->RemoveCallback();
545         refs_->DecRefCount();
546     }
547 
548     refs_ = other.refs_;
549     other.refs_ = nullptr;
550     return *this;
551 }
552 
~RefBase()553 RefBase::~RefBase()
554 {
555     if (refs_ != nullptr) {
556         refs_->RemoveCallback();
557         if ((refs_->IsLifeTimeExtended() && refs_->GetWeakRefCount() == 0) ||
558              refs_->GetStrongRefCount() == INITIAL_PRIMARY_VALUE) {
559             refs_->DecRefCount();
560         }
561         refs_ = nullptr;
562     }
563 }
564 
ExtendObjectLifetime()565 void RefBase::ExtendObjectLifetime()
566 {
567     refs_->ExtendObjectLifetime();
568 }
569 
IncStrongRef(const void * objectId)570 void RefBase::IncStrongRef(const void *objectId)
571 {
572     if (refs_ == nullptr) {
573         return;
574     }
575 
576     IncWeakRef(objectId);
577     const int curCount = refs_->IncStrongRefCount(objectId);
578     if (!refs_->IsLifeTimeExtended() && curCount == 0) {
579         UTILS_LOGF("RefBase object still incStrongRef after last strong ref");
580     }
581     if (curCount == INITIAL_PRIMARY_VALUE) {
582         OnFirstStrongRef(objectId);
583     }
584 }
585 
CheckIsAttemptAcquireSet(const void * objectId)586 void RefBase::CheckIsAttemptAcquireSet(const void *objectId)
587 {
588     if (refs_->IsAttemptAcquireSet()) {
589         refs_->ClearAttemptAcquire();
590         const int attemptCount = refs_->GetAttemptAcquire();
591         if (attemptCount < 0) {
592             UTILS_LOGF("Multi-threads trigger illegal decstrong from %{public}d due to AttemptIncStrong in ipc",
593                 attemptCount);
594         }
595         refs_->DecStrongRefCount(objectId);
596         refs_->DecWeakRefCount(objectId);
597     }
598 }
599 
DecStrongRef(const void * objectId)600 void RefBase::DecStrongRef(const void *objectId)
601 {
602     if (refs_ == nullptr) {
603         return;
604     }
605 
606     RefCounter * const refs = refs_;
607     const int curCount = refs->DecStrongRefCount(objectId);
608     if (curCount <= 0) {
609         UTILS_LOGF("RefBase object call decStrongRef too many times");
610     }
611     if (curCount == 1) {
612         std::atomic_thread_fence(std::memory_order_acquire);
613         OnLastStrongRef(objectId);
614         if (!refs->IsLifeTimeExtended()) {
615             if (refs->callback_) {
616                 refs->callback_();
617             }
618         }
619     }
620 
621     refs->DecWeakRefCount(objectId);
622 }
623 
GetSptrRefCount()624 int RefBase::GetSptrRefCount()
625 {
626     if (refs_ == nullptr) {
627         return 0;
628     }
629     return refs_->GetStrongRefCount();
630 }
631 
CreateWeakRef(void * cookie)632 WeakRefCounter *RefBase::CreateWeakRef(void *cookie)
633 {
634     if (refs_ != nullptr) {
635         return new WeakRefCounter(refs_, cookie);
636     }
637     return nullptr;
638 }
639 
IncWeakRef(const void * objectId)640 void RefBase::IncWeakRef(const void *objectId)
641 {
642     if (refs_ != nullptr) {
643         refs_->IncWeakRefCount(objectId);
644     }
645 }
646 
GetRefCounter() const647 RefCounter *RefBase::GetRefCounter() const
648 {
649     return refs_;
650 }
651 
DecWeakRef(const void * objectId)652 void RefBase::DecWeakRef(const void *objectId)
653 {
654     if (refs_ != nullptr) {
655         refs_->DecWeakRefCount(objectId);
656     }
657 }
658 
GetWptrRefCount()659 int RefBase::GetWptrRefCount()
660 {
661     if (refs_ == nullptr) {
662         return 0;
663     }
664     return refs_->GetWeakRefCount();
665 }
666 
AttemptAcquire(const void * objectId)667 bool RefBase::AttemptAcquire(const void *objectId)
668 {
669     if (refs_ == nullptr) {
670         return false;
671     }
672 
673     int count = 0;
674     if (refs_->AttemptIncStrongRef(objectId, count)) {
675         refs_->SetAttemptAcquire();
676         if (count == INITIAL_PRIMARY_VALUE) {
677             OnFirstStrongRef(objectId);
678         }
679 
680         return true;
681     }
682     return false;
683 }
684 
AttemptIncStrongRef(const void * objectId)685 bool RefBase::AttemptIncStrongRef(const void *objectId)
686 {
687     if ((refs_ != nullptr) && (OnAttemptPromoted(objectId))) {
688         int count = 0;
689         bool ret = refs_->AttemptIncStrongRef(objectId, count);
690         if (count == INITIAL_PRIMARY_VALUE) {
691             OnFirstStrongRef(objectId);
692         }
693         return ret;
694     }
695 
696     return false;
697 }
698 
AttemptIncStrong(const void * objectId)699 bool RefBase::AttemptIncStrong(const void *objectId)
700 {
701     if (refs_ == nullptr) {
702         return false;
703     }
704     if (refs_->AttemptIncStrong(objectId)) {
705         refs_->SetAttemptAcquire();
706         return true;
707     }
708     return false;
709 }
710 
IsAttemptAcquireSet()711 bool RefBase::IsAttemptAcquireSet()
712 {
713     if (refs_ == nullptr) {
714         return false;
715     }
716     return refs_->IsAttemptAcquireSet();
717 }
718 
IsExtendLifeTimeSet()719 bool RefBase::IsExtendLifeTimeSet()
720 {
721     if (refs_ == nullptr) {
722         return false;
723     }
724     return refs_->IsLifeTimeExtended();
725 }
726 
OnFirstStrongRef(const void *)727 void RefBase::OnFirstStrongRef(const void*)
728 {}
729 
OnLastStrongRef(const void *)730 void RefBase::OnLastStrongRef(const void*)
731 {}
732 
OnLastWeakRef(const void *)733 void RefBase::OnLastWeakRef(const void*)
734 {}
735 
OnAttemptPromoted(const void *)736 bool RefBase::OnAttemptPromoted(const void*)
737 {
738     return true;
739 }
740 
741 #if ((defined DEBUG_REFBASE) && (!defined TRACK_ALL))
EnableTracker()742 void RefBase::EnableTracker()
743 {
744     refs_->EnableTracker();
745 }
746 #else
EnableTracker()747 void RefBase::EnableTracker()
748 {
749 }
750 #endif
751 
EnableTrackerWithDomainId(unsigned int domainId)752 void RefBase::EnableTrackerWithDomainId(unsigned int domainId)
753 {
754 #if ((defined DEBUG_REFBASE) && (defined PRINT_TRACK_AT_ONCE))
755     refs_->EnableTrackerWithDomainId(domainId);
756 #endif
757 }
758 
759 }  // namespace OHOS
760