]> git.saurik.com Git - apple/icu.git/blame_incremental - icuSources/common/sharedobject.h
ICU-551.24.tar.gz
[apple/icu.git] / icuSources / common / sharedobject.h
... / ...
CommitLineData
1/*
2******************************************************************************
3* Copyright (C) 2014, International Business Machines
4* Corporation and others. All Rights Reserved.
5******************************************************************************
6* sharedobject.h
7*/
8
9#ifndef __SHAREDOBJECT_H__
10#define __SHAREDOBJECT_H__
11
12
13#include "unicode/uobject.h"
14#include "umutex.h"
15
16U_NAMESPACE_BEGIN
17
18/**
19 * Base class for shared, reference-counted, auto-deleted objects.
20 * Subclasses can be immutable.
21 * If they are mutable, then they must implement their copy constructor
22 * so that copyOnWrite() works.
23 *
24 * Either stack-allocate, use LocalPointer, or use addRef()/removeRef().
25 * Sharing requires reference-counting.
26 */
27class U_COMMON_API SharedObject : public UObject {
28public:
29 /** Initializes totalRefCount, softRefCount to 0. */
30 SharedObject() : totalRefCount(0), softRefCount(0) {}
31
32 /** Initializes totalRefCount, softRefCount to 0. */
33 SharedObject(const SharedObject &other)
34 : UObject(other),
35 totalRefCount(0),
36 softRefCount(0) {}
37
38 virtual ~SharedObject();
39
40 /**
41 * Increments the number of references to this object. Thread-safe.
42 */
43 void addRef() const;
44
45 /**
46 * Increments the number of soft references to this object. Thread-safe.
47 */
48 void addSoftRef() const;
49
50 /**
51 * Decrements the number of references to this object. Thread-safe.
52 */
53 void removeRef() const;
54
55 /**
56 * Decrements the number of soft references to this object. Thread-safe.
57 */
58 void removeSoftRef() const;
59
60 /**
61 * Returns the reference counter including soft references.
62 * Uses a memory barrier.
63 */
64 int32_t getRefCount() const;
65
66 /**
67 * Returns the count of soft references only. Uses a memory barrier.
68 * Used for testing the cache. Regular clients won't need this.
69 */
70 int32_t getSoftRefCount() const;
71
72 /**
73 * If allSoftReferences() == TRUE then this object has only soft
74 * references. The converse is not necessarily true.
75 */
76 UBool allSoftReferences() const;
77
78 /**
79 * Deletes this object if it has no references or soft references.
80 */
81 void deleteIfZeroRefCount() const;
82
83 /**
84 * Returns a writable version of ptr.
85 * If there is exactly one owner, then ptr itself is returned as a
86 * non-const pointer.
87 * If there are multiple owners, then ptr is replaced with a
88 * copy-constructed clone,
89 * and that is returned.
90 * Returns NULL if cloning failed.
91 *
92 * T must be a subclass of SharedObject.
93 */
94 template<typename T>
95 static T *copyOnWrite(const T *&ptr) {
96 const T *p = ptr;
97 if(p->getRefCount() <= 1) { return const_cast<T *>(p); }
98 T *p2 = new T(*p);
99 if(p2 == NULL) { return NULL; }
100 p->removeRef();
101 ptr = p2;
102 p2->addRef();
103 return p2;
104 }
105
106 /**
107 * Makes dest an owner of the object pointed to by src while adjusting
108 * reference counts and deleting the previous object dest pointed to
109 * if necessary. Before this call is made, dest must either be NULL or
110 * be included in the reference count of the object it points to.
111 *
112 * T must be a subclass of SharedObject.
113 */
114 template<typename T>
115 static void copyPtr(const T *src, const T *&dest) {
116 if(src != dest) {
117 if(dest != NULL) { dest->removeRef(); }
118 dest = src;
119 if(src != NULL) { src->addRef(); }
120 }
121 }
122
123 /**
124 * Equivalent to copyPtr(NULL, dest).
125 */
126 template<typename T>
127 static void clearPtr(const T *&ptr) {
128 if (ptr != NULL) {
129 ptr->removeRef();
130 ptr = NULL;
131 }
132 }
133
134private:
135 mutable u_atomic_int32_t totalRefCount;
136 mutable u_atomic_int32_t softRefCount;
137};
138
139U_NAMESPACE_END
140
141#endif