LCOV - code coverage report
Current view: top level - intl/icu/source/common - sharedobject.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 36 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 32 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // © 2016 and later: Unicode, Inc. and others.
       2             : // License & terms of use: http://www.unicode.org/copyright.html
       3             : /*
       4             : ******************************************************************************
       5             : * Copyright (C) 2015-2016, International Business Machines
       6             : * Corporation and others.  All Rights Reserved.
       7             : ******************************************************************************
       8             : * sharedobject.h
       9             : */
      10             : 
      11             : #ifndef __SHAREDOBJECT_H__
      12             : #define __SHAREDOBJECT_H__
      13             : 
      14             : 
      15             : #include "unicode/uobject.h"
      16             : #include "umutex.h"
      17             : 
      18             : U_NAMESPACE_BEGIN
      19             : 
      20             : /**
      21             :  * Base class for unified cache exposing enough methods to SharedObject
      22             :  * instances to allow their addRef() and removeRef() methods to
      23             :  * update cache metrics. No other part of ICU, except for SharedObject,
      24             :  * should directly call the methods of this base class.
      25             :  */
      26             : class U_COMMON_API UnifiedCacheBase : public UObject {
      27             : public:
      28           0 :     UnifiedCacheBase() { }
      29             : 
      30             :     /**
      31             :      * Called by addRefWhileHoldingCacheLock() when the hard reference count
      32             :      * of its instance goes from 0 to 1.
      33             :      */
      34             :     virtual void incrementItemsInUse() const = 0;
      35             : 
      36             :     /**
      37             :      * Called by removeRef() when the hard reference count of its instance
      38             :      * drops from 1 to 0.
      39             :      */
      40             :     virtual void decrementItemsInUseWithLockingAndEviction() const = 0;
      41             : 
      42             :     /**
      43             :      * Called by removeRefWhileHoldingCacheLock() when the hard reference
      44             :      * count of its instance drops from 1 to 0.
      45             :      */
      46             :     virtual void decrementItemsInUse() const = 0;
      47             :     virtual ~UnifiedCacheBase();
      48             : private:
      49             :     UnifiedCacheBase(const UnifiedCacheBase &);
      50             :     UnifiedCacheBase &operator=(const UnifiedCacheBase &);
      51             : };
      52             : 
      53             : /**
      54             :  * Base class for shared, reference-counted, auto-deleted objects.
      55             :  * Subclasses can be immutable.
      56             :  * If they are mutable, then they must implement their copy constructor
      57             :  * so that copyOnWrite() works.
      58             :  *
      59             :  * Either stack-allocate, use LocalPointer, or use addRef()/removeRef().
      60             :  * Sharing requires reference-counting.
      61             :  */
      62             : class U_COMMON_API SharedObject : public UObject {
      63             : public:
      64             :     /** Initializes totalRefCount, softRefCount to 0. */
      65           0 :     SharedObject() :
      66             :             totalRefCount(0),
      67             :             softRefCount(0),
      68             :             hardRefCount(0),
      69           0 :             cachePtr(NULL) {}
      70             : 
      71             :     /** Initializes totalRefCount, softRefCount to 0. */
      72           0 :     SharedObject(const SharedObject &other) :
      73             :             UObject(other),
      74             :             totalRefCount(0),
      75             :             softRefCount(0),
      76             :             hardRefCount(0),
      77           0 :             cachePtr(NULL) {}
      78             : 
      79             :     virtual ~SharedObject();
      80             : 
      81             :     /**
      82             :      * Increments the number of references to this object. Thread-safe.
      83             :      */
      84           0 :     void addRef() const { addRef(FALSE); }
      85             : 
      86             :     /**
      87             :      * Increments the number of references to this object.
      88             :      * Must be called only from within the internals of UnifiedCache and
      89             :      * only while the cache global mutex is held.
      90             :      */
      91           0 :     void addRefWhileHoldingCacheLock() const { addRef(TRUE); }
      92             : 
      93             :     /**
      94             :      * Increments the number of soft references to this object.
      95             :      * Must be called only from within the internals of UnifiedCache and
      96             :      * only while the cache global mutex is held.
      97             :      */
      98             :     void addSoftRef() const;
      99             : 
     100             :     /**
     101             :      * Decrements the number of references to this object. Thread-safe.
     102             :      */
     103           0 :     void removeRef() const { removeRef(FALSE); }
     104             : 
     105             :     /**
     106             :      * Decrements the number of references to this object.
     107             :      * Must be called only from within the internals of UnifiedCache and
     108             :      * only while the cache global mutex is held.
     109             :      */
     110           0 :     void removeRefWhileHoldingCacheLock() const { removeRef(TRUE); }
     111             : 
     112             :     /**
     113             :      * Decrements the number of soft references to this object.
     114             :      * Must be called only from within the internals of UnifiedCache and
     115             :      * only while the cache global mutex is held.
     116             :      */
     117             :     void removeSoftRef() const;
     118             : 
     119             :     /**
     120             :      * Returns the reference counter including soft references.
     121             :      * Uses a memory barrier.
     122             :      */
     123             :     int32_t getRefCount() const;
     124             : 
     125             :     /**
     126             :      * Returns the count of soft references only.
     127             :      * Must be called only from within the internals of UnifiedCache and
     128             :      * only while the cache global mutex is held.
     129             :      */
     130           0 :     int32_t getSoftRefCount() const { return softRefCount; }
     131             : 
     132             :     /**
     133             :      * Returns the count of hard references only. Uses a memory barrier.
     134             :      * Used for testing the cache. Regular clients won't need this.
     135             :      */
     136             :     int32_t getHardRefCount() const;
     137             : 
     138             :     /**
     139             :      * If noHardReferences() == TRUE then this object has no hard references.
     140             :      * Must be called only from within the internals of UnifiedCache.
     141             :      */
     142           0 :     inline UBool noHardReferences() const { return getHardRefCount() == 0; }
     143             : 
     144             :     /**
     145             :      * If hasHardReferences() == TRUE then this object has hard references.
     146             :      * Must be called only from within the internals of UnifiedCache.
     147             :      */
     148           0 :     inline UBool hasHardReferences() const { return getHardRefCount() != 0; }
     149             : 
     150             :     /**
     151             :      * If noSoftReferences() == TRUE then this object has no soft references.
     152             :      * Must be called only from within the internals of UnifiedCache and
     153             :      * only while the cache global mutex is held.
     154             :      */
     155           0 :     UBool noSoftReferences() const { return (softRefCount == 0); }
     156             : 
     157             :     /**
     158             :      * Deletes this object if it has no references or soft references.
     159             :      */
     160             :     void deleteIfZeroRefCount() const;
     161             : 
     162             :     /**
     163             :      * @internal For UnifedCache use only to register this object with itself.
     164             :      *   Must be called before this object is exposed to multiple threads.
     165             :      */ 
     166           0 :     void registerWithCache(const UnifiedCacheBase *ptr) const {
     167           0 :         cachePtr = ptr;
     168           0 :     }
     169             :         
     170             :     /**
     171             :      * Returns a writable version of ptr.
     172             :      * If there is exactly one owner, then ptr itself is returned as a
     173             :      *  non-const pointer.
     174             :      * If there are multiple owners, then ptr is replaced with a 
     175             :      * copy-constructed clone,
     176             :      * and that is returned.
     177             :      * Returns NULL if cloning failed.
     178             :      *
     179             :      * T must be a subclass of SharedObject.
     180             :      */
     181             :     template<typename T>
     182           0 :     static T *copyOnWrite(const T *&ptr) {
     183           0 :         const T *p = ptr;
     184           0 :         if(p->getRefCount() <= 1) { return const_cast<T *>(p); }
     185           0 :         T *p2 = new T(*p);
     186           0 :         if(p2 == NULL) { return NULL; }
     187           0 :         p->removeRef();
     188           0 :         ptr = p2;
     189           0 :         p2->addRef();
     190           0 :         return p2;
     191             :     }
     192             : 
     193             :     /**
     194             :      * Makes dest an owner of the object pointed to by src while adjusting
     195             :      * reference counts and deleting the previous object dest pointed to
     196             :      * if necessary. Before this call is made, dest must either be NULL or
     197             :      * be included in the reference count of the object it points to. 
     198             :      *
     199             :      * T must be a subclass of SharedObject.
     200             :      */
     201             :     template<typename T>
     202           0 :     static void copyPtr(const T *src, const T *&dest) {
     203           0 :         if(src != dest) {
     204           0 :             if(dest != NULL) { dest->removeRef(); }
     205           0 :             dest = src;
     206           0 :             if(src != NULL) { src->addRef(); }
     207             :         }
     208           0 :     }
     209             : 
     210             :     /**
     211             :      * Equivalent to copyPtr(NULL, dest).
     212             :      */
     213             :     template<typename T>
     214           0 :     static void clearPtr(const T *&ptr) {
     215           0 :         if (ptr != NULL) {
     216           0 :             ptr->removeRef();
     217           0 :             ptr = NULL;
     218             :         }
     219           0 :     }
     220             : 
     221             : private:
     222             :     mutable u_atomic_int32_t totalRefCount;
     223             : 
     224             :     // Any thread modifying softRefCount must hold the global cache mutex
     225             :     mutable int32_t softRefCount;
     226             : 
     227             :     mutable u_atomic_int32_t hardRefCount;
     228             :     mutable const UnifiedCacheBase *cachePtr;
     229             :     void addRef(UBool withCacheLock) const;
     230             :     void removeRef(UBool withCacheLock) const;
     231             : 
     232             : };
     233             : 
     234             : U_NAMESPACE_END
     235             : 
     236             : #endif

Generated by: LCOV version 1.13