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