| 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
|
|
|