Index: source/common/sharedobject.h |
diff --git a/source/common/sharedobject.h b/source/common/sharedobject.h |
index 432c79ba0b9c63e45dcb44f954833826139fe2a6..44028699975920a2a5ddf19e142cb8ad85eb2aea 100644 |
--- a/source/common/sharedobject.h |
+++ b/source/common/sharedobject.h |
@@ -1,6 +1,6 @@ |
/* |
****************************************************************************** |
-* Copyright (C) 2014, International Business Machines |
+* Copyright (C) 2015, International Business Machines |
* Corporation and others. All Rights Reserved. |
****************************************************************************** |
* sharedobject.h |
@@ -16,6 +16,39 @@ |
U_NAMESPACE_BEGIN |
/** |
+ * 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 UnifiedCacheBase : public UObject { |
+public: |
+ UnifiedCacheBase() { } |
+ |
+ /** |
+ * Called by addRefWhileHoldingCacheLock() when the hard reference count |
+ * of its instance goes from 0 to 1. |
+ */ |
+ virtual void incrementItemsInUse() const = 0; |
+ |
+ /** |
+ * Called by removeRef() when the hard reference count of its instance |
+ * drops from 1 to 0. |
+ */ |
+ virtual void decrementItemsInUseWithLockingAndEviction() const = 0; |
+ |
+ /** |
+ * Called by removeRefWhileHoldingCacheLock() when the hard reference |
+ * count of its instance drops from 1 to 0. |
+ */ |
+ virtual void decrementItemsInUse() 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. |
* If they are mutable, then they must implement their copy constructor |
@@ -27,33 +60,57 @@ U_NAMESPACE_BEGIN |
class U_COMMON_API SharedObject : public UObject { |
public: |
/** Initializes totalRefCount, softRefCount to 0. */ |
- SharedObject() : totalRefCount(0), softRefCount(0) {} |
+ SharedObject() : |
+ totalRefCount(0), |
+ 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), |
+ totalRefCount(0), |
+ softRefCount(0), |
+ hardRefCount(0), |
+ cachePtr(NULL) {} |
virtual ~SharedObject(); |
/** |
* Increments the number of references to this object. Thread-safe. |
*/ |
- void addRef() const; |
+ void addRef() const { addRef(FALSE); } |
+ |
+ /** |
+ * Increments the number of references to this object. |
+ * Must be called only from within the internals of UnifiedCache and |
+ * only while the cache global mutex is held. |
+ */ |
+ void addRefWhileHoldingCacheLock() const { addRef(TRUE); } |
/** |
- * Increments the number of soft references to this object. Thread-safe. |
+ * Increments the number of soft references to this object. |
+ * Must be called only from within the internals of UnifiedCache and |
+ * only while the cache global mutex is held. |
*/ |
void addSoftRef() const; |
/** |
* Decrements the number of references to this object. Thread-safe. |
*/ |
- void removeRef() const; |
+ void removeRef() const { removeRef(FALSE); } |
/** |
- * Decrements the number of soft references to this object. Thread-safe. |
+ * Decrements the number of references to this object. |
+ * Must be called only from within the internals of UnifiedCache and |
+ * only while the cache global mutex is held. |
+ */ |
+ void removeRefWhileHoldingCacheLock() const { removeRef(TRUE); } |
+ |
+ /** |
+ * Decrements the number of soft references to this object. |
+ * Must be called only from within the internals of UnifiedCache and |
+ * only while the cache global mutex is held. |
*/ |
void removeSoftRef() const; |
@@ -64,16 +121,36 @@ public: |
int32_t getRefCount() const; |
/** |
- * Returns the count of soft references only. Uses a memory barrier. |
+ * Returns the count of soft references only. |
+ * Must be called only from within the internals of UnifiedCache and |
+ * only while the cache global mutex is held. |
+ */ |
+ int32_t getSoftRefCount() const { return softRefCount; } |
+ |
+ /** |
+ * Returns the count of hard references only. Uses a memory barrier. |
* Used for testing the cache. Regular clients won't need this. |
*/ |
- int32_t getSoftRefCount() const; |
+ int32_t getHardRefCount() 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 getHardRefCount() == 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 getHardRefCount() != 0; } |
+ |
+ /** |
+ * If noSoftReferences() == TRUE then this object has no soft references. |
+ * Must be called only from within the internals of UnifiedCache and |
+ * only while the cache global mutex is held. |
+ */ |
+ UBool noSoftReferences() const { return (softRefCount == 0); } |
/** |
* Deletes this object if it has no references or soft references. |
@@ -81,6 +158,14 @@ public: |
void deleteIfZeroRefCount() const; |
/** |
+ * @internal For UnifedCache use only to register this object with itself. |
+ * Must be called before this object is exposed to multiple threads. |
+ */ |
+ void registerWithCache(const UnifiedCacheBase *ptr) const { |
+ cachePtr = ptr; |
+ } |
+ |
+ /** |
* Returns a writable version of ptr. |
* If there is exactly one owner, then ptr itself is returned as a |
* non-const pointer. |
@@ -133,7 +218,15 @@ public: |
private: |
mutable u_atomic_int32_t totalRefCount; |
- mutable u_atomic_int32_t softRefCount; |
+ |
+ // Any thread modifying softRefCount must hold the global cache mutex |
+ mutable int32_t softRefCount; |
+ |
+ mutable u_atomic_int32_t hardRefCount; |
+ mutable const UnifiedCacheBase *cachePtr; |
+ void addRef(UBool withCacheLock) const; |
+ void removeRef(UBool withCacheLock) const; |
+ |
}; |
U_NAMESPACE_END |