]>
Commit | Line | Data |
---|---|---|
bbc27441 | 1 | /* |
f70aedc4 | 2 | * Copyright (C) 1996-2021 The Squid Software Foundation and contributors |
bbc27441 AJ |
3 | * |
4 | * Squid software is distributed under GPLv2+ license and includes | |
5 | * contributions from numerous individuals and organizations. | |
6 | * Please see the COPYING and CONTRIBUTORS files for details. | |
7 | */ | |
8 | ||
4299f876 AR |
9 | #ifndef SQUID_CBC_POINTER_H |
10 | #define SQUID_CBC_POINTER_H | |
11 | ||
12 | #include "base/TextException.h" | |
13 | #include "cbdata.h" | |
0796f998 | 14 | #include "Debug.h" |
4299f876 AR |
15 | |
16 | /** | |
17 | \ingroup CBDATAAPI | |
18 | * | |
4cb2536f | 19 | * Safely points to a cbdata-protected class (cbc), such as an AsyncJob. |
4299f876 AR |
20 | * When a cbc we communicate with disappears without |
21 | * notice or a notice has not reached us yet, this class prevents | |
22 | * dereferencing the pointer to the gone cbc object. | |
23 | */ | |
24 | template<class Cbc> | |
25 | class CbcPointer | |
26 | { | |
27 | public: | |
28 | CbcPointer(); // a nil pointer | |
29 | CbcPointer(Cbc *aCbc); | |
30 | CbcPointer(const CbcPointer &p); | |
b9a9207b | 31 | CbcPointer(CbcPointer &&); |
4299f876 AR |
32 | ~CbcPointer(); |
33 | ||
34 | Cbc *raw() const; ///< a temporary raw Cbc pointer; may be invalid | |
35 | Cbc *get() const; ///< a temporary valid raw Cbc pointer or NULL | |
36 | Cbc &operator *() const; ///< a valid Cbc reference or exception | |
37 | Cbc *operator ->() const; ///< a valid Cbc pointer or exception | |
38 | ||
39 | // no bool operator because set() != valid() | |
40 | bool set() const { return cbc != NULL; } ///< was set but may be invalid | |
41 | Cbc *valid() const { return get(); } ///< was set and is valid | |
42 | bool operator !() const { return !valid(); } ///< invalid or was not set | |
43 | bool operator ==(const CbcPointer<Cbc> &o) const { return lock == o.lock; } | |
44 | ||
45 | CbcPointer &operator =(const CbcPointer &p); | |
b9a9207b | 46 | CbcPointer &operator =(CbcPointer &&); |
4299f876 AR |
47 | |
48 | /// support converting a child cbc pointer into a parent cbc pointer | |
49 | template <typename Other> | |
50 | CbcPointer(const CbcPointer<Other> &o): cbc(o.raw()), lock(NULL) { | |
51 | if (o.valid()) | |
52 | lock = cbdataReference(o->toCbdata()); | |
53 | } | |
54 | ||
55 | /// support assigning a child cbc pointer to a parent cbc pointer | |
56 | template <typename Other> | |
57 | CbcPointer &operator =(const CbcPointer<Other> &o) { | |
596e3d5f | 58 | if (this != &o) { // assignment to self |
6cb816e5 A |
59 | clear(); |
60 | cbc = o.raw(); // so that set() is accurate | |
61 | if (o.valid()) | |
62 | lock = cbdataReference(o->toCbdata()); | |
596e3d5f | 63 | } |
4299f876 AR |
64 | return *this; |
65 | } | |
66 | ||
67 | void clear(); ///< make pointer not set; does not invalidate cbdata | |
68 | ||
69 | std::ostream &print(std::ostream &os) const; | |
70 | ||
71 | private: | |
72 | Cbc *cbc; // a possibly invalid pointer to a cbdata class | |
73 | void *lock; // a valid pointer to cbc's cbdata or nil | |
74 | }; | |
75 | ||
76 | template <class Cbc> | |
77 | inline | |
4cb2536f A |
78 | std::ostream &operator <<(std::ostream &os, const CbcPointer<Cbc> &p) |
79 | { | |
4299f876 AR |
80 | return p.print(os); |
81 | } | |
82 | ||
83 | // inlined methods | |
84 | ||
85 | template<class Cbc> | |
86 | CbcPointer<Cbc>::CbcPointer(): cbc(NULL), lock(NULL) | |
87 | { | |
88 | } | |
89 | ||
90 | template<class Cbc> | |
91 | CbcPointer<Cbc>::CbcPointer(Cbc *aCbc): cbc(aCbc), lock(NULL) | |
92 | { | |
93 | if (cbc) | |
94 | lock = cbdataReference(cbc->toCbdata()); | |
95 | } | |
96 | ||
97 | template<class Cbc> | |
98 | CbcPointer<Cbc>::CbcPointer(const CbcPointer &d): cbc(d.cbc), lock(NULL) | |
99 | { | |
100 | if (d.lock && cbdataReferenceValid(d.lock)) | |
101 | lock = cbdataReference(d.lock); | |
102 | } | |
103 | ||
b9a9207b AJ |
104 | template<class Cbc> |
105 | CbcPointer<Cbc>::CbcPointer(CbcPointer &&d): cbc(d.cbc), lock(d.lock) | |
106 | { | |
107 | d.cbc = nullptr; | |
108 | d.lock = nullptr; | |
109 | } | |
110 | ||
4299f876 AR |
111 | template<class Cbc> |
112 | CbcPointer<Cbc>::~CbcPointer() | |
113 | { | |
114 | clear(); | |
115 | } | |
116 | ||
117 | template<class Cbc> | |
118 | CbcPointer<Cbc> &CbcPointer<Cbc>::operator =(const CbcPointer &d) | |
119 | { | |
596e3d5f | 120 | if (this != &d) { // assignment to self |
6cb816e5 A |
121 | clear(); |
122 | cbc = d.cbc; | |
123 | if (d.lock && cbdataReferenceValid(d.lock)) | |
124 | lock = cbdataReference(d.lock); | |
596e3d5f | 125 | } |
4299f876 AR |
126 | return *this; |
127 | } | |
128 | ||
b9a9207b AJ |
129 | template<class Cbc> |
130 | CbcPointer<Cbc> &CbcPointer<Cbc>::operator =(CbcPointer &&d) | |
131 | { | |
132 | if (this != &d) { // assignment to self | |
133 | clear(); | |
134 | cbc = d.cbc; | |
135 | d.cbc = nullptr; | |
136 | lock = d.lock; | |
137 | d.lock = nullptr; | |
138 | } | |
139 | return *this; | |
140 | } | |
141 | ||
4299f876 AR |
142 | template<class Cbc> |
143 | void | |
144 | CbcPointer<Cbc>::clear() | |
145 | { | |
0796f998 AJ |
146 | #if USE_CBDATA_DEBUG |
147 | debugs(45, 3, "cbc=" << (void*)cbc << ", lock=" << (void*)lock); | |
148 | #endif | |
4299f876 AR |
149 | cbdataReferenceDone(lock); // lock may be nil before and will be nil after |
150 | cbc = NULL; | |
151 | } | |
152 | ||
153 | template<class Cbc> | |
154 | Cbc * | |
155 | CbcPointer<Cbc>::raw() const | |
156 | { | |
157 | return cbc; | |
158 | } | |
159 | ||
160 | template<class Cbc> | |
161 | Cbc * | |
162 | CbcPointer<Cbc>::get() const | |
163 | { | |
164 | return (lock && cbdataReferenceValid(lock)) ? cbc : NULL; | |
165 | } | |
166 | ||
167 | template<class Cbc> | |
168 | Cbc & | |
169 | CbcPointer<Cbc>::operator *() const | |
170 | { | |
171 | Cbc *c = get(); | |
ca603620 | 172 | assert(c); |
4299f876 AR |
173 | return *c; |
174 | } | |
175 | ||
176 | template<class Cbc> | |
177 | Cbc * | |
178 | CbcPointer<Cbc>::operator ->() const | |
179 | { | |
180 | Cbc *c = get(); | |
ca603620 | 181 | assert(c); |
4299f876 AR |
182 | return c; |
183 | } | |
184 | ||
185 | template <class Cbc> | |
4cb2536f A |
186 | std::ostream &CbcPointer<Cbc>::print(std::ostream &os) const |
187 | { | |
4299f876 AR |
188 | return os << cbc << '/' << lock; |
189 | } | |
190 | ||
4299f876 | 191 | #endif /* SQUID_CBC_POINTER_H */ |
f53969cc | 192 |