| // Copyright (C) 2016 and later: Unicode, Inc. and others. |
| // License & terms of use: http://www.unicode.org/copyright.html |
| /* |
| ****************************************************************************** |
| * Copyright (C) 2015, International Business Machines |
| * Corporation and others. All Rights Reserved. |
| ****************************************************************************** |
| * sharedobject.cpp |
| */ |
| #include "sharedobject.h" |
| #include "uassert.h" |
| |
| U_NAMESPACE_BEGIN |
| |
| SharedObject::~SharedObject() {} |
| |
| UnifiedCacheBase::~UnifiedCacheBase() {} |
| |
| void |
| SharedObject::addRef(UBool fromWithinCache) const { |
| umtx_atomic_inc(&totalRefCount); |
| |
| // Although items in use may not be correct immediately, it |
| // will be correct eventually. |
| if (umtx_atomic_inc(&hardRefCount) == 1 && cachePtr != NULL) { |
| // If this object is cached, and the hardRefCount goes from 0 to 1, |
| // then the increment must happen from within the cache while the |
| // cache global mutex is locked. In this way, we can be rest assured |
| // that data races can't happen if the cache performs some task if |
| // the hardRefCount is zero while the global cache mutex is locked. |
| (void)fromWithinCache; // Suppress unused variable warning in non-debug builds. |
| U_ASSERT(fromWithinCache); |
| cachePtr->incrementItemsInUse(); |
| } |
| } |
| |
| void |
| SharedObject::removeRef(UBool fromWithinCache) const { |
| UBool decrementItemsInUse = (umtx_atomic_dec(&hardRefCount) == 0); |
| UBool allReferencesGone = (umtx_atomic_dec(&totalRefCount) == 0); |
| |
| // Although items in use may not be correct immediately, it |
| // will be correct eventually. |
| if (decrementItemsInUse && cachePtr != NULL) { |
| if (fromWithinCache) { |
| cachePtr->decrementItemsInUse(); |
| } else { |
| cachePtr->decrementItemsInUseWithLockingAndEviction(); |
| } |
| } |
| if (allReferencesGone) { |
| delete this; |
| } |
| } |
| |
| void |
| SharedObject::addSoftRef() const { |
| umtx_atomic_inc(&totalRefCount); |
| ++softRefCount; |
| } |
| |
| void |
| SharedObject::removeSoftRef() const { |
| --softRefCount; |
| if (umtx_atomic_dec(&totalRefCount) == 0) { |
| delete this; |
| } |
| } |
| |
| int32_t |
| SharedObject::getRefCount() const { |
| return umtx_loadAcquire(totalRefCount); |
| } |
| |
| int32_t |
| SharedObject::getHardRefCount() const { |
| return umtx_loadAcquire(hardRefCount); |
| } |
| |
| void |
| SharedObject::deleteIfZeroRefCount() const { |
| if(getRefCount() == 0) { |
| delete this; |
| } |
| } |
| |
| U_NAMESPACE_END |