]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/common/sharedobject.h
ICU-66108.tar.gz
[apple/icu.git] / icuSources / common / sharedobject.h
index 432c79ba0b9c63e45dcb44f954833826139fe2a6..c0a5aba4782821bb0bd24a0f068850e9b7af08e5 100644 (file)
@@ -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
 
 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.
@@ -27,59 +54,61 @@ U_NAMESPACE_BEGIN
 class U_COMMON_API SharedObject : public UObject {
 public:
     /** Initializes totalRefCount, softRefCount to 0. */
-    SharedObject() : totalRefCount(0), softRefCount(0) {}
+    SharedObject() :
+            softRefCount(0),
+            hardRefCount(0),
+            cachePtr(NULL) {}
 
     /** Initializes totalRefCount, softRefCount to 0. */
-    SharedObject(const SharedObject &other)
-        : UObject(other),
-          totalRefCount(0),
-          softRefCount(0) {}
+    SharedObject(const SharedObject &other) :
+            UObject(other),
+            softRefCount(0),
+            hardRefCount(0),
+            cachePtr(NULL) {}
 
     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;
 
     /**
-     * Increments the number of soft references to this object. Thread-safe.
-     */
-    void addSoftRef() const;
-
-    /**
-     * Decrements the number of references to this object. 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;
 
     /**
-     * Decrements the number of soft references to this object. Thread-safe.
-     */
-    void removeSoftRef() const;
-
-    /**
-     * Returns the reference counter including soft references.
+     * Returns the number of hard references for this object.
      * 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.
+     * If noHardReferences() == TRUE then this object has no hard references.
+     * Must be called only from within the internals of UnifiedCache.
      */
-    int32_t getSoftRefCount() const;
+    inline UBool noHardReferences() const { return getRefCount() == 0; }
 
     /**
-     * If allSoftReferences() == TRUE then this object has only soft
-     * references. The converse is not necessarily true.
+     * If hasHardReferences() == TRUE then this object has hard references.
+     * Must be called only from within the internals of UnifiedCache.
      */
-    UBool allSoftReferences() const;
+    inline UBool hasHardReferences() const { return getRefCount() != 0; }
 
     /**
-     * Deletes this object if it has no references or soft references.
+     * 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
@@ -132,8 +161,22 @@ public:
     }
 
 private:
-    mutable u_atomic_int32_t totalRefCount;
-    mutable u_atomic_int32_t softRefCount;
+    /**
+     * 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