X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/57a6839dcb3bba09e8228b822b290604668416fe..c5116b9f5a666b9d59f443b3770acd6ef64dc6c3:/icuSources/common/sharedobject.h diff --git a/icuSources/common/sharedobject.h b/icuSources/common/sharedobject.h index 671bab13..c0a5aba4 100644 --- a/icuSources/common/sharedobject.h +++ b/icuSources/common/sharedobject.h @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** -* Copyright (C) 2014, International Business Machines +* Copyright (C) 2015-2016, International Business Machines * Corporation and others. All Rights Reserved. ****************************************************************************** * sharedobject.h @@ -15,6 +17,31 @@ U_NAMESPACE_BEGIN +class SharedObject; + +/** + * Base class for unified cache exposing enough methods to SharedObject + * instances to allow their addRef() and removeRef() methods to + * update cache metrics. No other part of ICU, except for SharedObject, + * should directly call the methods of this base class. + */ +class U_COMMON_API UnifiedCacheBase : public UObject { +public: + UnifiedCacheBase() { } + + /** + * Notify the cache implementation that an object was seen transitioning to + * zero hard references. The cache may use this to keep track the number of + * unreferenced SharedObjects, and to trigger evictions. + */ + virtual void handleUnreferencedObject() const = 0; + + virtual ~UnifiedCacheBase(); +private: + UnifiedCacheBase(const UnifiedCacheBase &); + UnifiedCacheBase &operator=(const UnifiedCacheBase &); +}; + /** * Base class for shared, reference-counted, auto-deleted objects. * Subclasses can be immutable. @@ -26,31 +53,62 @@ U_NAMESPACE_BEGIN */ class U_COMMON_API SharedObject : public UObject { public: - /** Initializes refCount to 0. */ - SharedObject() : refCount(0) {} + /** Initializes totalRefCount, softRefCount to 0. */ + SharedObject() : + softRefCount(0), + hardRefCount(0), + cachePtr(NULL) {} + + /** Initializes totalRefCount, softRefCount to 0. */ + SharedObject(const SharedObject &other) : + UObject(other), + softRefCount(0), + hardRefCount(0), + cachePtr(NULL) {} - /** Initializes refCount to 0. */ - SharedObject(const SharedObject &/*other*/) : refCount(0) {} virtual ~SharedObject(); /** - * Increments the number of references to this object. Thread-safe. + * Increments the number of hard references to this object. Thread-safe. + * Not for use from within the Unified Cache implementation. */ void addRef() const; /** - * Decrements the number of references to this object, - * and auto-deletes "this" if the number becomes 0. Thread-safe. + * Decrements the number of hard references to this object, and + * arrange for possible cache-eviction and/or deletion if ref + * count goes to zero. Thread-safe. + * + * Not for use from within the UnifiedCache implementation. */ void removeRef() const; /** - * Returns the reference counter. Uses a memory barrier. + * Returns the number of hard references for this object. + * Uses a memory barrier. */ int32_t getRefCount() const; + /** + * If noHardReferences() == TRUE then this object has no hard references. + * Must be called only from within the internals of UnifiedCache. + */ + inline UBool noHardReferences() const { return getRefCount() == 0; } + + /** + * If hasHardReferences() == TRUE then this object has hard references. + * Must be called only from within the internals of UnifiedCache. + */ + inline UBool hasHardReferences() const { return getRefCount() != 0; } + + /** + * Deletes this object if it has no references. + * Available for non-cached SharedObjects only. Ownership of cached objects + * is with the UnifiedCache, which is solely responsible for eviction and deletion. + */ void deleteIfZeroRefCount() const; + /** * Returns a writable version of ptr. * If there is exactly one owner, then ptr itself is returned as a @@ -78,7 +136,7 @@ public: * 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 - * own its object. + * be included in the reference count of the object it points to. * * T must be a subclass of SharedObject. */ @@ -92,7 +150,7 @@ public: } /** - * Equivalent to copy(NULL, dest). + * Equivalent to copyPtr(NULL, dest). */ template static void clearPtr(const T *&ptr) { @@ -103,7 +161,22 @@ public: } private: - mutable u_atomic_int32_t refCount; + /** + * The number of references from the UnifiedCache, which is + * the number of times that the sharedObject is stored as a hash table value. + * For use by UnifiedCache implementation code only. + * All access is synchronized by UnifiedCache's gCacheMutex + */ + mutable int32_t softRefCount; + friend class UnifiedCache; + + /** + * Reference count, excluding references from within the UnifiedCache implementation. + */ + mutable u_atomic_int32_t hardRefCount; + + mutable const UnifiedCacheBase *cachePtr; + }; U_NAMESPACE_END