OLD | NEW |
(Empty) | |
| 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 |
| 16 U_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 */ |
| 27 class U_COMMON_API SharedObject : public UObject { |
| 28 public: |
| 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 |
| 134 private: |
| 135 mutable u_atomic_int32_t totalRefCount; |
| 136 mutable u_atomic_int32_t softRefCount; |
| 137 }; |
| 138 |
| 139 U_NAMESPACE_END |
| 140 |
| 141 #endif |
OLD | NEW |