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()15SharedObject::~SharedObject() {} 16 ~UnifiedCacheBase()17UnifiedCacheBase::~UnifiedCacheBase() {} 18 19 void addRef(UBool fromWithinCache) const20SharedObject::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) const38SharedObject::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() const57SharedObject::addSoftRef() const { 58 umtx_atomic_inc(&totalRefCount); 59 ++softRefCount; 60 } 61 62 void removeSoftRef() const63SharedObject::removeSoftRef() const { 64 --softRefCount; 65 if (umtx_atomic_dec(&totalRefCount) == 0) { 66 delete this; 67 } 68 } 69 70 int32_t getRefCount() const71SharedObject::getRefCount() const { 72 return umtx_loadAcquire(totalRefCount); 73 } 74 75 int32_t getHardRefCount() const76SharedObject::getHardRefCount() const { 77 return umtx_loadAcquire(hardRefCount); 78 } 79 80 void deleteIfZeroRefCount() const81SharedObject::deleteIfZeroRefCount() const { 82 if(getRefCount() == 0) { 83 delete this; 84 } 85 } 86 87 U_NAMESPACE_END 88