• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 refCount to 0. */
SharedObject()30     SharedObject() : refCount(0) {}
31 
32     /** Initializes refCount to 0. */
SharedObject(const SharedObject &)33     SharedObject(const SharedObject &/*other*/) : refCount(0) {}
34     virtual ~SharedObject();
35 
36     /**
37      * Increments the number of references to this object. Thread-safe.
38      */
39     void addRef() const;
40 
41     /**
42      * Decrements the number of references to this object,
43      * and auto-deletes "this" if the number becomes 0. Thread-safe.
44      */
45     void removeRef() const;
46 
47     /**
48      * Returns the reference counter. Uses a memory barrier.
49      */
50     int32_t getRefCount() const;
51 
52     void deleteIfZeroRefCount() const;
53 
54     /**
55      * Returns a writable version of ptr.
56      * If there is exactly one owner, then ptr itself is returned as a
57      *  non-const pointer.
58      * If there are multiple owners, then ptr is replaced with a
59      * copy-constructed clone,
60      * and that is returned.
61      * Returns NULL if cloning failed.
62      *
63      * T must be a subclass of SharedObject.
64      */
65     template<typename T>
copyOnWrite(const T * & ptr)66     static T *copyOnWrite(const T *&ptr) {
67         const T *p = ptr;
68         if(p->getRefCount() <= 1) { return const_cast<T *>(p); }
69         T *p2 = new T(*p);
70         if(p2 == NULL) { return NULL; }
71         p->removeRef();
72         ptr = p2;
73         p2->addRef();
74         return p2;
75     }
76 
77     /**
78      * Makes dest an owner of the object pointed to by src while adjusting
79      * reference counts and deleting the previous object dest pointed to
80      * if necessary. Before this call is made, dest must either be NULL or
81      * own its object.
82      *
83      * T must be a subclass of SharedObject.
84      */
85     template<typename T>
copyPtr(const T * src,const T * & dest)86     static void copyPtr(const T *src, const T *&dest) {
87         if(src != dest) {
88             if(dest != NULL) { dest->removeRef(); }
89             dest = src;
90             if(src != NULL) { src->addRef(); }
91         }
92     }
93 
94     /**
95      * Equivalent to copy(NULL, dest).
96      */
97     template<typename T>
clearPtr(const T * & ptr)98     static void clearPtr(const T *&ptr) {
99         if (ptr != NULL) {
100             ptr->removeRef();
101             ptr = NULL;
102         }
103     }
104 
105 private:
106     mutable u_atomic_int32_t refCount;
107 };
108 
109 U_NAMESPACE_END
110 
111 #endif
112