]> git.saurik.com Git - apple/icu.git/blame - icuSources/common/sharedobject.h
ICU-64260.0.1.tar.gz
[apple/icu.git] / icuSources / common / sharedobject.h
CommitLineData
f3c0d7a5
A
1// © 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html
57a6839d
A
3/*
4******************************************************************************
2ca993e8 5* Copyright (C) 2015-2016, International Business Machines
57a6839d
A
6* Corporation and others. All Rights Reserved.
7******************************************************************************
8* sharedobject.h
9*/
10
11#ifndef __SHAREDOBJECT_H__
12#define __SHAREDOBJECT_H__
13
14
15#include "unicode/uobject.h"
16#include "umutex.h"
17
18U_NAMESPACE_BEGIN
19
0f5d89e8
A
20class SharedObject;
21
2ca993e8
A
22/**
23 * Base class for unified cache exposing enough methods to SharedObject
24 * instances to allow their addRef() and removeRef() methods to
25 * update cache metrics. No other part of ICU, except for SharedObject,
26 * should directly call the methods of this base class.
27 */
28class U_COMMON_API UnifiedCacheBase : public UObject {
29public:
30 UnifiedCacheBase() { }
31
32 /**
0f5d89e8
A
33 * Notify the cache implementation that an object was seen transitioning to
34 * zero hard references. The cache may use this to keep track the number of
35 * unreferenced SharedObjects, and to trigger evictions.
2ca993e8 36 */
0f5d89e8 37 virtual void handleUnreferencedObject() const = 0;
2ca993e8 38
2ca993e8
A
39 virtual ~UnifiedCacheBase();
40private:
41 UnifiedCacheBase(const UnifiedCacheBase &);
42 UnifiedCacheBase &operator=(const UnifiedCacheBase &);
43};
44
57a6839d
A
45/**
46 * Base class for shared, reference-counted, auto-deleted objects.
47 * Subclasses can be immutable.
48 * If they are mutable, then they must implement their copy constructor
49 * so that copyOnWrite() works.
50 *
51 * Either stack-allocate, use LocalPointer, or use addRef()/removeRef().
52 * Sharing requires reference-counting.
53 */
54class U_COMMON_API SharedObject : public UObject {
55public:
b331163b 56 /** Initializes totalRefCount, softRefCount to 0. */
2ca993e8 57 SharedObject() :
2ca993e8
A
58 softRefCount(0),
59 hardRefCount(0),
60 cachePtr(NULL) {}
b331163b
A
61
62 /** Initializes totalRefCount, softRefCount to 0. */
2ca993e8
A
63 SharedObject(const SharedObject &other) :
64 UObject(other),
2ca993e8
A
65 softRefCount(0),
66 hardRefCount(0),
67 cachePtr(NULL) {}
57a6839d 68
57a6839d
A
69 virtual ~SharedObject();
70
71 /**
0f5d89e8
A
72 * Increments the number of hard references to this object. Thread-safe.
73 * Not for use from within the Unified Cache implementation.
2ca993e8 74 */
0f5d89e8 75 void addRef() const;
2ca993e8
A
76
77 /**
0f5d89e8
A
78 * Decrements the number of hard references to this object, and
79 * arrange for possible cache-eviction and/or deletion if ref
80 * count goes to zero. Thread-safe.
81 *
82 * Not for use from within the UnifiedCache implementation.
b331163b 83 */
0f5d89e8 84 void removeRef() const;
b331163b
A
85
86 /**
0f5d89e8 87 * Returns the number of hard references for this object.
b331163b 88 * Uses a memory barrier.
57a6839d
A
89 */
90 int32_t getRefCount() const;
91
2ca993e8
A
92 /**
93 * If noHardReferences() == TRUE then this object has no hard references.
94 * Must be called only from within the internals of UnifiedCache.
95 */
0f5d89e8 96 inline UBool noHardReferences() const { return getRefCount() == 0; }
b331163b
A
97
98 /**
2ca993e8
A
99 * If hasHardReferences() == TRUE then this object has hard references.
100 * Must be called only from within the internals of UnifiedCache.
b331163b 101 */
0f5d89e8 102 inline UBool hasHardReferences() const { return getRefCount() != 0; }
2ca993e8
A
103
104 /**
0f5d89e8
A
105 * Deletes this object if it has no references.
106 * Available for non-cached SharedObjects only. Ownership of cached objects
3d1f044b 107 * is with the UnifiedCache, which is solely responsible for eviction and deletion.
b331163b 108 */
57a6839d
A
109 void deleteIfZeroRefCount() const;
110
2ca993e8 111
57a6839d
A
112 /**
113 * Returns a writable version of ptr.
114 * If there is exactly one owner, then ptr itself is returned as a
115 * non-const pointer.
116 * If there are multiple owners, then ptr is replaced with a
117 * copy-constructed clone,
118 * and that is returned.
119 * Returns NULL if cloning failed.
120 *
121 * T must be a subclass of SharedObject.
122 */
123 template<typename T>
124 static T *copyOnWrite(const T *&ptr) {
125 const T *p = ptr;
126 if(p->getRefCount() <= 1) { return const_cast<T *>(p); }
127 T *p2 = new T(*p);
128 if(p2 == NULL) { return NULL; }
129 p->removeRef();
130 ptr = p2;
131 p2->addRef();
132 return p2;
133 }
134
135 /**
136 * Makes dest an owner of the object pointed to by src while adjusting
137 * reference counts and deleting the previous object dest pointed to
138 * if necessary. Before this call is made, dest must either be NULL or
b331163b 139 * be included in the reference count of the object it points to.
57a6839d
A
140 *
141 * T must be a subclass of SharedObject.
142 */
143 template<typename T>
144 static void copyPtr(const T *src, const T *&dest) {
145 if(src != dest) {
146 if(dest != NULL) { dest->removeRef(); }
147 dest = src;
148 if(src != NULL) { src->addRef(); }
149 }
150 }
151
152 /**
b331163b 153 * Equivalent to copyPtr(NULL, dest).
57a6839d
A
154 */
155 template<typename T>
156 static void clearPtr(const T *&ptr) {
157 if (ptr != NULL) {
158 ptr->removeRef();
159 ptr = NULL;
160 }
161 }
162
163private:
0f5d89e8
A
164 /**
165 * The number of references from the UnifiedCache, which is
166 * the number of times that the sharedObject is stored as a hash table value.
167 * For use by UnifiedCache implementation code only.
168 * All access is synchronized by UnifiedCache's gCacheMutex
169 */
2ca993e8 170 mutable int32_t softRefCount;
0f5d89e8 171 friend class UnifiedCache;
2ca993e8 172
0f5d89e8
A
173 /**
174 * Reference count, excluding references from within the UnifiedCache implementation.
175 */
2ca993e8 176 mutable u_atomic_int32_t hardRefCount;
0f5d89e8 177
2ca993e8 178 mutable const UnifiedCacheBase *cachePtr;
2ca993e8 179
57a6839d
A
180};
181
182U_NAMESPACE_END
183
184#endif