• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /*
4 ******************************************************************************
5 * Copyright (C) 2015, International Business Machines
6 * Corporation and others.  All Rights Reserved.
7 ******************************************************************************
8 * sharedobject.cpp
9 */
10 #include "sharedobject.h"
11 #include "uassert.h"
12 
13 U_NAMESPACE_BEGIN
14 
~SharedObject()15 SharedObject::~SharedObject() {}
16 
~UnifiedCacheBase()17 UnifiedCacheBase::~UnifiedCacheBase() {}
18 
19 void
addRef(UBool fromWithinCache) const20 SharedObject::addRef(UBool fromWithinCache) const {
21     umtx_atomic_inc(&totalRefCount);
22 
23     // Although items in use may not be correct immediately, it
24     // will be correct eventually.
25     if (umtx_atomic_inc(&hardRefCount) == 1 && cachePtr != NULL) {
26         // If this object is cached, and the hardRefCount goes from 0 to 1,
27         // then the increment must happen from within the cache while the
28         // cache global mutex is locked. In this way, we can be rest assured
29         // that data races can't happen if the cache performs some task if
30         // the hardRefCount is zero while the global cache mutex is locked.
31         (void)fromWithinCache;   // Suppress unused variable warning in non-debug builds.
32         U_ASSERT(fromWithinCache);
33         cachePtr->incrementItemsInUse();
34     }
35 }
36 
37 void
removeRef(UBool fromWithinCache) const38 SharedObject::removeRef(UBool fromWithinCache) const {
39     UBool decrementItemsInUse = (umtx_atomic_dec(&hardRefCount) == 0);
40     UBool allReferencesGone = (umtx_atomic_dec(&totalRefCount) == 0);
41 
42     // Although items in use may not be correct immediately, it
43     // will be correct eventually.
44     if (decrementItemsInUse && cachePtr != NULL) {
45         if (fromWithinCache) {
46             cachePtr->decrementItemsInUse();
47         } else {
48             cachePtr->decrementItemsInUseWithLockingAndEviction();
49         }
50     }
51     if (allReferencesGone) {
52         delete this;
53     }
54 }
55 
56 void
addSoftRef() const57 SharedObject::addSoftRef() const {
58     umtx_atomic_inc(&totalRefCount);
59     ++softRefCount;
60 }
61 
62 void
removeSoftRef() const63 SharedObject::removeSoftRef() const {
64     --softRefCount;
65     if (umtx_atomic_dec(&totalRefCount) == 0) {
66         delete this;
67     }
68 }
69 
70 int32_t
getRefCount() const71 SharedObject::getRefCount() const {
72     return umtx_loadAcquire(totalRefCount);
73 }
74 
75 int32_t
getHardRefCount() const76 SharedObject::getHardRefCount() const {
77     return umtx_loadAcquire(hardRefCount);
78 }
79 
80 void
deleteIfZeroRefCount() const81 SharedObject::deleteIfZeroRefCount() const {
82     if(getRefCount() == 0) {
83         delete this;
84     }
85 }
86 
87 U_NAMESPACE_END
88