| Index: source/common/sharedobject.h
|
| diff --git a/source/common/sharedobject.h b/source/common/sharedobject.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..432c79ba0b9c63e45dcb44f954833826139fe2a6
|
| --- /dev/null
|
| +++ b/source/common/sharedobject.h
|
| @@ -0,0 +1,141 @@
|
| +/*
|
| +******************************************************************************
|
| +* Copyright (C) 2014, International Business Machines
|
| +* Corporation and others. All Rights Reserved.
|
| +******************************************************************************
|
| +* sharedobject.h
|
| +*/
|
| +
|
| +#ifndef __SHAREDOBJECT_H__
|
| +#define __SHAREDOBJECT_H__
|
| +
|
| +
|
| +#include "unicode/uobject.h"
|
| +#include "umutex.h"
|
| +
|
| +U_NAMESPACE_BEGIN
|
| +
|
| +/**
|
| + * Base class for shared, reference-counted, auto-deleted objects.
|
| + * Subclasses can be immutable.
|
| + * If they are mutable, then they must implement their copy constructor
|
| + * so that copyOnWrite() works.
|
| + *
|
| + * Either stack-allocate, use LocalPointer, or use addRef()/removeRef().
|
| + * Sharing requires reference-counting.
|
| + */
|
| +class U_COMMON_API SharedObject : public UObject {
|
| +public:
|
| + /** Initializes totalRefCount, softRefCount to 0. */
|
| + SharedObject() : totalRefCount(0), softRefCount(0) {}
|
| +
|
| + /** Initializes totalRefCount, softRefCount to 0. */
|
| + SharedObject(const SharedObject &other)
|
| + : UObject(other),
|
| + totalRefCount(0),
|
| + softRefCount(0) {}
|
| +
|
| + virtual ~SharedObject();
|
| +
|
| + /**
|
| + * Increments the number of references to this object. Thread-safe.
|
| + */
|
| + void addRef() const;
|
| +
|
| + /**
|
| + * Increments the number of soft references to this object. Thread-safe.
|
| + */
|
| + void addSoftRef() const;
|
| +
|
| + /**
|
| + * Decrements the number of references to this object. Thread-safe.
|
| + */
|
| + void removeRef() const;
|
| +
|
| + /**
|
| + * Decrements the number of soft references to this object. Thread-safe.
|
| + */
|
| + void removeSoftRef() const;
|
| +
|
| + /**
|
| + * Returns the reference counter including soft references.
|
| + * Uses a memory barrier.
|
| + */
|
| + int32_t getRefCount() const;
|
| +
|
| + /**
|
| + * Returns the count of soft references only. Uses a memory barrier.
|
| + * Used for testing the cache. Regular clients won't need this.
|
| + */
|
| + int32_t getSoftRefCount() const;
|
| +
|
| + /**
|
| + * If allSoftReferences() == TRUE then this object has only soft
|
| + * references. The converse is not necessarily true.
|
| + */
|
| + UBool allSoftReferences() const;
|
| +
|
| + /**
|
| + * Deletes this object if it has no references or soft references.
|
| + */
|
| + void deleteIfZeroRefCount() const;
|
| +
|
| + /**
|
| + * Returns a writable version of ptr.
|
| + * If there is exactly one owner, then ptr itself is returned as a
|
| + * non-const pointer.
|
| + * If there are multiple owners, then ptr is replaced with a
|
| + * copy-constructed clone,
|
| + * and that is returned.
|
| + * Returns NULL if cloning failed.
|
| + *
|
| + * T must be a subclass of SharedObject.
|
| + */
|
| + template<typename T>
|
| + static T *copyOnWrite(const T *&ptr) {
|
| + const T *p = ptr;
|
| + if(p->getRefCount() <= 1) { return const_cast<T *>(p); }
|
| + T *p2 = new T(*p);
|
| + if(p2 == NULL) { return NULL; }
|
| + p->removeRef();
|
| + ptr = p2;
|
| + p2->addRef();
|
| + return p2;
|
| + }
|
| +
|
| + /**
|
| + * Makes dest an owner of the object pointed to by src while adjusting
|
| + * reference counts and deleting the previous object dest pointed to
|
| + * if necessary. Before this call is made, dest must either be NULL or
|
| + * be included in the reference count of the object it points to.
|
| + *
|
| + * T must be a subclass of SharedObject.
|
| + */
|
| + template<typename T>
|
| + static void copyPtr(const T *src, const T *&dest) {
|
| + if(src != dest) {
|
| + if(dest != NULL) { dest->removeRef(); }
|
| + dest = src;
|
| + if(src != NULL) { src->addRef(); }
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Equivalent to copyPtr(NULL, dest).
|
| + */
|
| + template<typename T>
|
| + static void clearPtr(const T *&ptr) {
|
| + if (ptr != NULL) {
|
| + ptr->removeRef();
|
| + ptr = NULL;
|
| + }
|
| + }
|
| +
|
| +private:
|
| + mutable u_atomic_int32_t totalRefCount;
|
| + mutable u_atomic_int32_t softRefCount;
|
| +};
|
| +
|
| +U_NAMESPACE_END
|
| +
|
| +#endif
|
|
|