Imported Upstream version 58.1
[platform/upstream/icu.git] / source / common / sharedobject.cpp
1 // Copyright (C) 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
15 SharedObject::~SharedObject() {}
16
17 UnifiedCacheBase::~UnifiedCacheBase() {}
18
19 void
20 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
38 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
57 SharedObject::addSoftRef() const {
58     umtx_atomic_inc(&totalRefCount);
59     ++softRefCount;
60 }
61
62 void
63 SharedObject::removeSoftRef() const {
64     --softRefCount;
65     if (umtx_atomic_dec(&totalRefCount) == 0) {
66         delete this;
67     }
68 }
69
70 int32_t
71 SharedObject::getRefCount() const {
72     return umtx_loadAcquire(totalRefCount);
73 }
74
75 int32_t
76 SharedObject::getHardRefCount() const {
77     return umtx_loadAcquire(hardRefCount);
78 }
79
80 void
81 SharedObject::deleteIfZeroRefCount() const {
82     if(getRefCount() == 0) {
83         delete this;
84     }
85 }
86
87 U_NAMESPACE_END