tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

sharedobject.h (5819B)


      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 class SharedObject;
     21 
     22 /**
     23 * Base class for unified cache exposing enough methods to SharedObject
     24 * instances to allow their addRef() and removeRef() methods to
     25 * update cache metrics. No other part of ICU, except for SharedObject,
     26 * should directly call the methods of this base class.
     27 */
     28 class U_COMMON_API UnifiedCacheBase : public UObject {
     29 public:
     30    UnifiedCacheBase() { }
     31 
     32    /**
     33     * Notify the cache implementation that an object was seen transitioning to
     34     * zero hard references. The cache may use this to keep track the number of
     35     * unreferenced SharedObjects, and to trigger evictions.
     36     */
     37    virtual void handleUnreferencedObject() const = 0;
     38 
     39    virtual ~UnifiedCacheBase();
     40 private:
     41    UnifiedCacheBase(const UnifiedCacheBase &) = delete;
     42    UnifiedCacheBase &operator=(const UnifiedCacheBase &) = delete;
     43 };
     44 
     45 /**
     46 * Base class for shared, reference-counted, auto-deleted objects.
     47 * Subclasses can be immutable.
     48 * If they are mutable, then they must implement their copy constructor
     49 * so that copyOnWrite() works.
     50 *
     51 * Either stack-allocate, use LocalPointer, or use addRef()/removeRef().
     52 * Sharing requires reference-counting.
     53 */
     54 class U_COMMON_API_CLASS SharedObject : public UObject {
     55 public:
     56    /** Initializes totalRefCount, softRefCount to 0. */
     57    U_COMMON_API SharedObject() :
     58            softRefCount(0),
     59            hardRefCount(0),
     60            cachePtr(nullptr) {}
     61 
     62    /** Initializes totalRefCount, softRefCount to 0. */
     63    U_COMMON_API SharedObject(const SharedObject &other) :
     64            UObject(other),
     65            softRefCount(0),
     66            hardRefCount(0),
     67            cachePtr(nullptr) {}
     68 
     69    U_COMMON_API virtual ~SharedObject();
     70 
     71    /**
     72     * Increments the number of hard references to this object. Thread-safe.
     73     * Not for use from within the Unified Cache implementation.
     74     */
     75    U_COMMON_API void addRef() const;
     76 
     77    /**
     78     * Decrements the number of hard references to this object, and
     79     * arrange for possible cache-eviction and/or deletion if ref
     80     * count goes to zero. Thread-safe.
     81     * 
     82     * Not for use from within the UnifiedCache implementation.
     83     */
     84    U_COMMON_API void removeRef() const;
     85 
     86    /**
     87     * Returns the number of hard references for this object.
     88     * Uses a memory barrier.
     89     */
     90    U_COMMON_API int32_t getRefCount() const;
     91 
     92    /**
     93     * If noHardReferences() == true then this object has no hard references.
     94     * Must be called only from within the internals of UnifiedCache.
     95     */
     96    U_COMMON_API inline UBool noHardReferences() const { return getRefCount() == 0; }
     97 
     98    /**
     99     * If hasHardReferences() == true then this object has hard references.
    100     * Must be called only from within the internals of UnifiedCache.
    101     */
    102    U_COMMON_API inline UBool hasHardReferences() const { return getRefCount() != 0; }
    103 
    104    /**
    105     * Deletes this object if it has no references.
    106     * Available for non-cached SharedObjects only. Ownership of cached objects
    107     * is with the UnifiedCache, which is solely responsible for eviction and deletion.
    108     */
    109    U_COMMON_API void deleteIfZeroRefCount() const;
    110 
    111        
    112    /**
    113     * Returns a writable version of ptr.
    114     * If there is exactly one owner, then ptr itself is returned as a
    115     *  non-const pointer.
    116     * If there are multiple owners, then ptr is replaced with a 
    117     * copy-constructed clone,
    118     * and that is returned.
    119     * Returns nullptr if cloning failed.
    120     *
    121     * T must be a subclass of SharedObject.
    122     */
    123    template<typename T>
    124    static T *copyOnWrite(const T *&ptr) {
    125        const T *p = ptr;
    126        if(p->getRefCount() <= 1) { return const_cast<T *>(p); }
    127        T *p2 = new T(*p);
    128        if(p2 == nullptr) { return nullptr; }
    129        p->removeRef();
    130        ptr = p2;
    131        p2->addRef();
    132        return p2;
    133    }
    134 
    135    /**
    136     * Makes dest an owner of the object pointed to by src while adjusting
    137     * reference counts and deleting the previous object dest pointed to
    138     * if necessary. Before this call is made, dest must either be nullptr or
    139     * be included in the reference count of the object it points to. 
    140     *
    141     * T must be a subclass of SharedObject.
    142     */
    143    template<typename T>
    144    static void copyPtr(const T *src, const T *&dest) {
    145        if(src != dest) {
    146            if(dest != nullptr) { dest->removeRef(); }
    147            dest = src;
    148            if(src != nullptr) { src->addRef(); }
    149        }
    150    }
    151 
    152    /**
    153     * Equivalent to copyPtr(nullptr, dest).
    154     */
    155    template<typename T>
    156    static void clearPtr(const T *&ptr) {
    157        if (ptr != nullptr) {
    158            ptr->removeRef();
    159            ptr = nullptr;
    160        }
    161    }
    162 
    163 private:
    164    /**
    165     * The number of references from the UnifiedCache, which is
    166     * the number of times that the sharedObject is stored as a hash table value.
    167     * For use by UnifiedCache implementation code only.
    168     * All access is synchronized by UnifiedCache's gCacheMutex
    169     */
    170    mutable int32_t softRefCount;
    171    friend class UnifiedCache;
    172 
    173    /**
    174     * Reference count, excluding references from within the UnifiedCache implementation.
    175     */
    176    mutable u_atomic_int32_t hardRefCount;
    177    
    178    mutable const UnifiedCacheBase *cachePtr;
    179 
    180 };
    181 
    182 U_NAMESPACE_END
    183 
    184 #endif