]> git.ipfire.org Git - thirdparty/squid.git/blame - src/base/CbcPointer.h
Boilerplate: update copyright blurbs on Squid helpers
[thirdparty/squid.git] / src / base / CbcPointer.h
CommitLineData
4299f876
AR
1#ifndef SQUID_CBC_POINTER_H
2#define SQUID_CBC_POINTER_H
3
4#include "base/TextException.h"
5#include "cbdata.h"
6
7/**
8 \ingroup CBDATAAPI
9 *
4cb2536f 10 * Safely points to a cbdata-protected class (cbc), such as an AsyncJob.
4299f876
AR
11 * When a cbc we communicate with disappears without
12 * notice or a notice has not reached us yet, this class prevents
13 * dereferencing the pointer to the gone cbc object.
14 */
15template<class Cbc>
16class CbcPointer
17{
18public:
19 CbcPointer(); // a nil pointer
20 CbcPointer(Cbc *aCbc);
21 CbcPointer(const CbcPointer &p);
22 ~CbcPointer();
23
24 Cbc *raw() const; ///< a temporary raw Cbc pointer; may be invalid
25 Cbc *get() const; ///< a temporary valid raw Cbc pointer or NULL
26 Cbc &operator *() const; ///< a valid Cbc reference or exception
27 Cbc *operator ->() const; ///< a valid Cbc pointer or exception
28
29 // no bool operator because set() != valid()
30 bool set() const { return cbc != NULL; } ///< was set but may be invalid
31 Cbc *valid() const { return get(); } ///< was set and is valid
32 bool operator !() const { return !valid(); } ///< invalid or was not set
33 bool operator ==(const CbcPointer<Cbc> &o) const { return lock == o.lock; }
34
35 CbcPointer &operator =(const CbcPointer &p);
36
37 /// support converting a child cbc pointer into a parent cbc pointer
38 template <typename Other>
39 CbcPointer(const CbcPointer<Other> &o): cbc(o.raw()), lock(NULL) {
40 if (o.valid())
41 lock = cbdataReference(o->toCbdata());
42 }
43
44 /// support assigning a child cbc pointer to a parent cbc pointer
45 template <typename Other>
46 CbcPointer &operator =(const CbcPointer<Other> &o) {
596e3d5f 47 if (this != &o) { // assignment to self
6cb816e5
A
48 clear();
49 cbc = o.raw(); // so that set() is accurate
50 if (o.valid())
51 lock = cbdataReference(o->toCbdata());
596e3d5f 52 }
4299f876
AR
53 return *this;
54 }
55
56 void clear(); ///< make pointer not set; does not invalidate cbdata
57
58 std::ostream &print(std::ostream &os) const;
59
60private:
61 Cbc *cbc; // a possibly invalid pointer to a cbdata class
62 void *lock; // a valid pointer to cbc's cbdata or nil
63};
64
65template <class Cbc>
66inline
4cb2536f
A
67std::ostream &operator <<(std::ostream &os, const CbcPointer<Cbc> &p)
68{
4299f876
AR
69 return p.print(os);
70}
71
72// inlined methods
73
74template<class Cbc>
75CbcPointer<Cbc>::CbcPointer(): cbc(NULL), lock(NULL)
76{
77}
78
79template<class Cbc>
80CbcPointer<Cbc>::CbcPointer(Cbc *aCbc): cbc(aCbc), lock(NULL)
81{
82 if (cbc)
83 lock = cbdataReference(cbc->toCbdata());
84}
85
86template<class Cbc>
87CbcPointer<Cbc>::CbcPointer(const CbcPointer &d): cbc(d.cbc), lock(NULL)
88{
89 if (d.lock && cbdataReferenceValid(d.lock))
90 lock = cbdataReference(d.lock);
91}
92
93template<class Cbc>
94CbcPointer<Cbc>::~CbcPointer()
95{
96 clear();
97}
98
99template<class Cbc>
100CbcPointer<Cbc> &CbcPointer<Cbc>::operator =(const CbcPointer &d)
101{
596e3d5f 102 if (this != &d) { // assignment to self
6cb816e5
A
103 clear();
104 cbc = d.cbc;
105 if (d.lock && cbdataReferenceValid(d.lock))
106 lock = cbdataReference(d.lock);
596e3d5f 107 }
4299f876
AR
108 return *this;
109}
110
111template<class Cbc>
112void
113CbcPointer<Cbc>::clear()
114{
115 cbdataReferenceDone(lock); // lock may be nil before and will be nil after
116 cbc = NULL;
117}
118
119template<class Cbc>
120Cbc *
121CbcPointer<Cbc>::raw() const
122{
123 return cbc;
124}
125
126template<class Cbc>
127Cbc *
128CbcPointer<Cbc>::get() const
129{
130 return (lock && cbdataReferenceValid(lock)) ? cbc : NULL;
131}
132
133template<class Cbc>
134Cbc &
135CbcPointer<Cbc>::operator *() const
136{
137 Cbc *c = get();
ca603620 138 assert(c);
4299f876
AR
139 return *c;
140}
141
142template<class Cbc>
143Cbc *
144CbcPointer<Cbc>::operator ->() const
145{
146 Cbc *c = get();
ca603620 147 assert(c);
4299f876
AR
148 return c;
149}
150
151template <class Cbc>
4cb2536f
A
152std::ostream &CbcPointer<Cbc>::print(std::ostream &os) const
153{
4299f876
AR
154 return os << cbc << '/' << lock;
155}
156
4299f876 157#endif /* SQUID_CBC_POINTER_H */