Coverage Report

Created: 2025-06-24 06:43

/src/icu/source/common/sharedobject.h
Line
Count
Source (jump to first uncovered line)
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
0
    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 &);
42
    UnifiedCacheBase &operator=(const UnifiedCacheBase &);
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 SharedObject : public UObject {
55
public:
56
    /** Initializes totalRefCount, softRefCount to 0. */
57
    SharedObject() :
58
0
            softRefCount(0),
59
0
            hardRefCount(0),
60
0
            cachePtr(NULL) {}
61
62
    /** Initializes totalRefCount, softRefCount to 0. */
63
    SharedObject(const SharedObject &other) :
64
0
            UObject(other),
65
0
            softRefCount(0),
66
0
            hardRefCount(0),
67
0
            cachePtr(NULL) {}
68
69
    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
    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
    void removeRef() const;
85
86
    /**
87
     * Returns the number of hard references for this object.
88
     * Uses a memory barrier.
89
     */
90
    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
0
    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
0
    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
    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 NULL if cloning failed.
120
     *
121
     * T must be a subclass of SharedObject.
122
     */
123
    template<typename T>
124
0
    static T *copyOnWrite(const T *&ptr) {
125
0
        const T *p = ptr;
126
0
        if(p->getRefCount() <= 1) { return const_cast<T *>(p); }
127
0
        T *p2 = new T(*p);
128
0
        if(p2 == NULL) { return NULL; }
129
0
        p->removeRef();
130
0
        ptr = p2;
131
0
        p2->addRef();
132
0
        return p2;
133
0
    }
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 NULL 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
0
    static void copyPtr(const T *src, const T *&dest) {
145
0
        if(src != dest) {
146
0
            if(dest != NULL) { dest->removeRef(); }
147
0
            dest = src;
148
0
            if(src != NULL) { src->addRef(); }
149
0
        }
150
0
    }
Unexecuted instantiation: void icu_70::SharedObject::copyPtr<icu_70::CollationCacheEntry>(icu_70::CollationCacheEntry const*, icu_70::CollationCacheEntry const*&)
Unexecuted instantiation: void icu_70::SharedObject::copyPtr<icu_70::DateFmtBestPattern>(icu_70::DateFmtBestPattern const*, icu_70::DateFmtBestPattern const*&)
Unexecuted instantiation: void icu_70::SharedObject::copyPtr<icu_70::SharedDateFormatSymbols>(icu_70::SharedDateFormatSymbols const*, icu_70::SharedDateFormatSymbols const*&)
Unexecuted instantiation: void icu_70::SharedObject::copyPtr<icu_70::CollationSettings>(icu_70::CollationSettings const*, icu_70::CollationSettings const*&)
Unexecuted instantiation: void icu_70::SharedObject::copyPtr<icu_70::SharedNumberFormat>(icu_70::SharedNumberFormat const*, icu_70::SharedNumberFormat const*&)
Unexecuted instantiation: void icu_70::SharedObject::copyPtr<icu_70::SharedCalendar>(icu_70::SharedCalendar const*, icu_70::SharedCalendar const*&)
Unexecuted instantiation: void icu_70::SharedObject::copyPtr<icu_70::SharedPluralRules>(icu_70::SharedPluralRules const*, icu_70::SharedPluralRules const*&)
Unexecuted instantiation: void icu_70::SharedObject::copyPtr<icu_70::SharedObject>(icu_70::SharedObject const*, icu_70::SharedObject const*&)
151
152
    /**
153
     * Equivalent to copyPtr(NULL, dest).
154
     */
155
    template<typename T>
156
0
    static void clearPtr(const T *&ptr) {
157
0
        if (ptr != NULL) {
158
0
            ptr->removeRef();
159
0
            ptr = NULL;
160
0
        }
161
0
    }
Unexecuted instantiation: void icu_70::SharedObject::clearPtr<icu_70::CollationCacheEntry>(icu_70::CollationCacheEntry const*&)
Unexecuted instantiation: void icu_70::SharedObject::clearPtr<icu_70::CollationSettings>(icu_70::CollationSettings const*&)
Unexecuted instantiation: void icu_70::SharedObject::clearPtr<icu_70::CollationTailoring>(icu_70::CollationTailoring const*&)
Unexecuted instantiation: void icu_70::SharedObject::clearPtr<icu_70::DateFmtBestPattern>(icu_70::DateFmtBestPattern const*&)
Unexecuted instantiation: void icu_70::SharedObject::clearPtr<icu_70::SharedDateFormatSymbols>(icu_70::SharedDateFormatSymbols const*&)
Unexecuted instantiation: void icu_70::SharedObject::clearPtr<icu_70::SharedNumberFormat>(icu_70::SharedNumberFormat const*&)
Unexecuted instantiation: void icu_70::SharedObject::clearPtr<icu_70::SharedCalendar>(icu_70::SharedCalendar const*&)
Unexecuted instantiation: void icu_70::SharedObject::clearPtr<icu_70::SharedPluralRules>(icu_70::SharedPluralRules const*&)
Unexecuted instantiation: void icu_70::SharedObject::clearPtr<icu_70::SharedObject>(icu_70::SharedObject const*&)
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