]> git.ipfire.org Git - thirdparty/squid.git/blob - src/base/CbcPointer.h
SourceFormat Enforcement
[thirdparty/squid.git] / src / base / CbcPointer.h
1 /*
2 * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
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
9 #ifndef SQUID_CBC_POINTER_H
10 #define SQUID_CBC_POINTER_H
11
12 #include "base/TextException.h"
13 #include "cbdata.h"
14 #include "Debug.h"
15
16 /**
17 \ingroup CBDATAAPI
18 *
19 * Safely points to a cbdata-protected class (cbc), such as an AsyncJob.
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);
31 ~CbcPointer();
32
33 Cbc *raw() const; ///< a temporary raw Cbc pointer; may be invalid
34 Cbc *get() const; ///< a temporary valid raw Cbc pointer or NULL
35 Cbc &operator *() const; ///< a valid Cbc reference or exception
36 Cbc *operator ->() const; ///< a valid Cbc pointer or exception
37
38 // no bool operator because set() != valid()
39 bool set() const { return cbc != NULL; } ///< was set but may be invalid
40 Cbc *valid() const { return get(); } ///< was set and is valid
41 bool operator !() const { return !valid(); } ///< invalid or was not set
42 bool operator ==(const CbcPointer<Cbc> &o) const { return lock == o.lock; }
43
44 CbcPointer &operator =(const CbcPointer &p);
45
46 /// support converting a child cbc pointer into a parent cbc pointer
47 template <typename Other>
48 CbcPointer(const CbcPointer<Other> &o): cbc(o.raw()), lock(NULL) {
49 if (o.valid())
50 lock = cbdataReference(o->toCbdata());
51 }
52
53 /// support assigning a child cbc pointer to a parent cbc pointer
54 template <typename Other>
55 CbcPointer &operator =(const CbcPointer<Other> &o) {
56 if (this != &o) { // assignment to self
57 clear();
58 cbc = o.raw(); // so that set() is accurate
59 if (o.valid())
60 lock = cbdataReference(o->toCbdata());
61 }
62 return *this;
63 }
64
65 void clear(); ///< make pointer not set; does not invalidate cbdata
66
67 std::ostream &print(std::ostream &os) const;
68
69 private:
70 Cbc *cbc; // a possibly invalid pointer to a cbdata class
71 void *lock; // a valid pointer to cbc's cbdata or nil
72 };
73
74 template <class Cbc>
75 inline
76 std::ostream &operator <<(std::ostream &os, const CbcPointer<Cbc> &p)
77 {
78 return p.print(os);
79 }
80
81 // inlined methods
82
83 template<class Cbc>
84 CbcPointer<Cbc>::CbcPointer(): cbc(NULL), lock(NULL)
85 {
86 }
87
88 template<class Cbc>
89 CbcPointer<Cbc>::CbcPointer(Cbc *aCbc): cbc(aCbc), lock(NULL)
90 {
91 if (cbc)
92 lock = cbdataReference(cbc->toCbdata());
93 }
94
95 template<class Cbc>
96 CbcPointer<Cbc>::CbcPointer(const CbcPointer &d): cbc(d.cbc), lock(NULL)
97 {
98 if (d.lock && cbdataReferenceValid(d.lock))
99 lock = cbdataReference(d.lock);
100 }
101
102 template<class Cbc>
103 CbcPointer<Cbc>::~CbcPointer()
104 {
105 clear();
106 }
107
108 template<class Cbc>
109 CbcPointer<Cbc> &CbcPointer<Cbc>::operator =(const CbcPointer &d)
110 {
111 if (this != &d) { // assignment to self
112 clear();
113 cbc = d.cbc;
114 if (d.lock && cbdataReferenceValid(d.lock))
115 lock = cbdataReference(d.lock);
116 }
117 return *this;
118 }
119
120 template<class Cbc>
121 void
122 CbcPointer<Cbc>::clear()
123 {
124 #if USE_CBDATA_DEBUG
125 debugs(45, 3, "cbc=" << (void*)cbc << ", lock=" << (void*)lock);
126 #endif
127 cbdataReferenceDone(lock); // lock may be nil before and will be nil after
128 cbc = NULL;
129 }
130
131 template<class Cbc>
132 Cbc *
133 CbcPointer<Cbc>::raw() const
134 {
135 return cbc;
136 }
137
138 template<class Cbc>
139 Cbc *
140 CbcPointer<Cbc>::get() const
141 {
142 return (lock && cbdataReferenceValid(lock)) ? cbc : NULL;
143 }
144
145 template<class Cbc>
146 Cbc &
147 CbcPointer<Cbc>::operator *() const
148 {
149 Cbc *c = get();
150 assert(c);
151 return *c;
152 }
153
154 template<class Cbc>
155 Cbc *
156 CbcPointer<Cbc>::operator ->() const
157 {
158 Cbc *c = get();
159 assert(c);
160 return c;
161 }
162
163 template <class Cbc>
164 std::ostream &CbcPointer<Cbc>::print(std::ostream &os) const
165 {
166 return os << cbc << '/' << lock;
167 }
168
169 #endif /* SQUID_CBC_POINTER_H */
170