]> git.ipfire.org Git - thirdparty/squid.git/blob - src/base/CbcPointer.h
Bug #2583 fix: pure virtual method called
[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 clear();
52 cbc = o.raw(); // so that set() is accurate
53 if (o.valid())
54 lock = cbdataReference(o->toCbdata());
55 return *this;
56 }
57
58 void clear(); ///< make pointer not set; does not invalidate cbdata
59
60 std::ostream &print(std::ostream &os) const;
61
62 private:
63 Cbc *cbc; // a possibly invalid pointer to a cbdata class
64 void *lock; // a valid pointer to cbc's cbdata or nil
65 };
66
67 template <class Cbc>
68 inline
69 std::ostream &operator <<(std::ostream &os, const CbcPointer<Cbc> &p) {
70 return p.print(os);
71 }
72
73 // inlined methods
74
75 template<class Cbc>
76 CbcPointer<Cbc>::CbcPointer(): cbc(NULL), lock(NULL)
77 {
78 }
79
80 template<class Cbc>
81 CbcPointer<Cbc>::CbcPointer(Cbc *aCbc): cbc(aCbc), lock(NULL)
82 {
83 if (cbc)
84 lock = cbdataReference(cbc->toCbdata());
85 }
86
87 template<class Cbc>
88 CbcPointer<Cbc>::CbcPointer(const CbcPointer &d): cbc(d.cbc), lock(NULL)
89 {
90 if (d.lock && cbdataReferenceValid(d.lock))
91 lock = cbdataReference(d.lock);
92 }
93
94 template<class Cbc>
95 CbcPointer<Cbc>::~CbcPointer()
96 {
97 clear();
98 }
99
100 template<class Cbc>
101 CbcPointer<Cbc> &CbcPointer<Cbc>::operator =(const CbcPointer &d)
102 {
103 clear();
104 cbc = d.cbc;
105 if (d.lock && cbdataReferenceValid(d.lock))
106 lock = cbdataReference(d.lock);
107 return *this;
108 }
109
110 template<class Cbc>
111 void
112 CbcPointer<Cbc>::clear()
113 {
114 cbdataReferenceDone(lock); // lock may be nil before and will be nil after
115 cbc = NULL;
116 }
117
118 template<class Cbc>
119 Cbc *
120 CbcPointer<Cbc>::raw() const
121 {
122 return cbc;
123 }
124
125 template<class Cbc>
126 Cbc *
127 CbcPointer<Cbc>::get() const
128 {
129 return (lock && cbdataReferenceValid(lock)) ? cbc : NULL;
130 }
131
132 template<class Cbc>
133 Cbc &
134 CbcPointer<Cbc>::operator *() const
135 {
136 Cbc *c = get();
137 Must(c);
138 return *c;
139 }
140
141 template<class Cbc>
142 Cbc *
143 CbcPointer<Cbc>::operator ->() const
144 {
145 Cbc *c = get();
146 Must(c);
147 return c;
148 }
149
150 template <class Cbc>
151 std::ostream &CbcPointer<Cbc>::print(std::ostream &os) const {
152 return os << cbc << '/' << lock;
153 }
154
155
156 #endif /* SQUID_CBC_POINTER_H */