]> git.ipfire.org Git - thirdparty/squid.git/blame - src/base/CbcPointer.h
Source Format Enforcement (#763)
[thirdparty/squid.git] / src / base / CbcPointer.h
CommitLineData
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 */
24template<class Cbc>
25class CbcPointer
26{
27public:
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
71private:
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
76template <class Cbc>
77inline
4cb2536f
A
78std::ostream &operator <<(std::ostream &os, const CbcPointer<Cbc> &p)
79{
4299f876
AR
80 return p.print(os);
81}
82
83// inlined methods
84
85template<class Cbc>
86CbcPointer<Cbc>::CbcPointer(): cbc(NULL), lock(NULL)
87{
88}
89
90template<class Cbc>
91CbcPointer<Cbc>::CbcPointer(Cbc *aCbc): cbc(aCbc), lock(NULL)
92{
93 if (cbc)
94 lock = cbdataReference(cbc->toCbdata());
95}
96
97template<class Cbc>
98CbcPointer<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
104template<class Cbc>
105CbcPointer<Cbc>::CbcPointer(CbcPointer &&d): cbc(d.cbc), lock(d.lock)
106{
107 d.cbc = nullptr;
108 d.lock = nullptr;
109}
110
4299f876
AR
111template<class Cbc>
112CbcPointer<Cbc>::~CbcPointer()
113{
114 clear();
115}
116
117template<class Cbc>
118CbcPointer<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
129template<class Cbc>
130CbcPointer<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
142template<class Cbc>
143void
144CbcPointer<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
153template<class Cbc>
154Cbc *
155CbcPointer<Cbc>::raw() const
156{
157 return cbc;
158}
159
160template<class Cbc>
161Cbc *
162CbcPointer<Cbc>::get() const
163{
164 return (lock && cbdataReferenceValid(lock)) ? cbc : NULL;
165}
166
167template<class Cbc>
168Cbc &
169CbcPointer<Cbc>::operator *() const
170{
171 Cbc *c = get();
ca603620 172 assert(c);
4299f876
AR
173 return *c;
174}
175
176template<class Cbc>
177Cbc *
178CbcPointer<Cbc>::operator ->() const
179{
180 Cbc *c = get();
ca603620 181 assert(c);
4299f876
AR
182 return c;
183}
184
185template <class Cbc>
4cb2536f
A
186std::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