1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 ******************************************************************************
5 * Copyright (C) 2015-2016, International Business Machines
6 * Corporation and others. All Rights Reserved.
7 ******************************************************************************
11 #ifndef __SHAREDOBJECT_H__
12 #define __SHAREDOBJECT_H__
15 #include "unicode/uobject.h"
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.
28 class U_COMMON_API UnifiedCacheBase
: public UObject
{
30 UnifiedCacheBase() { }
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.
37 virtual void handleUnreferencedObject() const = 0;
39 virtual ~UnifiedCacheBase();
41 UnifiedCacheBase(const UnifiedCacheBase
&);
42 UnifiedCacheBase
&operator=(const UnifiedCacheBase
&);
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.
51 * Either stack-allocate, use LocalPointer, or use addRef()/removeRef().
52 * Sharing requires reference-counting.
54 class U_COMMON_API SharedObject
: public UObject
{
56 /** Initializes totalRefCount, softRefCount to 0. */
62 /** Initializes totalRefCount, softRefCount to 0. */
63 SharedObject(const SharedObject
&other
) :
69 virtual ~SharedObject();
72 * Increments the number of hard references to this object. Thread-safe.
73 * Not for use from within the Unified Cache implementation.
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.
82 * Not for use from within the UnifiedCache implementation.
84 void removeRef() const;
87 * Returns the number of hard references for this object.
88 * Uses a memory barrier.
90 int32_t getRefCount() const;
93 * If noHardReferences() == TRUE then this object has no hard references.
94 * Must be called only from within the internals of UnifiedCache.
96 inline UBool
noHardReferences() const { return getRefCount() == 0; }
99 * If hasHardReferences() == TRUE then this object has hard references.
100 * Must be called only from within the internals of UnifiedCache.
102 inline UBool
hasHardReferences() const { return getRefCount() != 0; }
105 * Deletes this object if it has no references.
106 * Available for non-cached SharedObjects only. Ownership of cached objects
107 * is with the UnifiedCache, which is soley responsible for eviction and deletion.
109 void deleteIfZeroRefCount() const;
113 * Returns a writable version of ptr.
114 * If there is exactly one owner, then ptr itself is returned as a
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.
121 * T must be a subclass of SharedObject.
124 static T
*copyOnWrite(const T
*&ptr
) {
126 if(p
->getRefCount() <= 1) { return const_cast<T
*>(p
); }
128 if(p2
== NULL
) { return NULL
; }
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
139 * be included in the reference count of the object it points to.
141 * T must be a subclass of SharedObject.
144 static void copyPtr(const T
*src
, const T
*&dest
) {
146 if(dest
!= NULL
) { dest
->removeRef(); }
148 if(src
!= NULL
) { src
->addRef(); }
153 * Equivalent to copyPtr(NULL, dest).
156 static void clearPtr(const T
*&ptr
) {
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
170 mutable int32_t softRefCount
;
171 friend class UnifiedCache
;
174 * Reference count, excluding references from within the UnifiedCache implementation.
176 mutable u_atomic_int32_t hardRefCount
;
178 mutable const UnifiedCacheBase
*cachePtr
;