]> git.ipfire.org Git - thirdparty/squid.git/blame - src/base/CbcPointer.h
SourceFormat Enforcement
[thirdparty/squid.git] / src / base / CbcPointer.h
CommitLineData
4299f876
AR
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 *
4cb2536f 14 * Safely points to a cbdata-protected class (cbc), such as an AsyncJob.
4299f876
AR
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 */
19template<class Cbc>
20class CbcPointer
21{
22public:
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) {
596e3d5f 51 if (this != &o) { // assignment to self
6cb816e5
A
52 clear();
53 cbc = o.raw(); // so that set() is accurate
54 if (o.valid())
55 lock = cbdataReference(o->toCbdata());
596e3d5f 56 }
4299f876
AR
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
64private:
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
69template <class Cbc>
70inline
4cb2536f
A
71std::ostream &operator <<(std::ostream &os, const CbcPointer<Cbc> &p)
72{
4299f876
AR
73 return p.print(os);
74}
75
76// inlined methods
77
78template<class Cbc>
79CbcPointer<Cbc>::CbcPointer(): cbc(NULL), lock(NULL)
80{
81}
82
83template<class Cbc>
84CbcPointer<Cbc>::CbcPointer(Cbc *aCbc): cbc(aCbc), lock(NULL)
85{
86 if (cbc)
87 lock = cbdataReference(cbc->toCbdata());
88}
89
90template<class Cbc>
91CbcPointer<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
97template<class Cbc>
98CbcPointer<Cbc>::~CbcPointer()
99{
100 clear();
101}
102
103template<class Cbc>
104CbcPointer<Cbc> &CbcPointer<Cbc>::operator =(const CbcPointer &d)
105{
596e3d5f 106 if (this != &d) { // assignment to self
6cb816e5
A
107 clear();
108 cbc = d.cbc;
109 if (d.lock && cbdataReferenceValid(d.lock))
110 lock = cbdataReference(d.lock);
596e3d5f 111 }
4299f876
AR
112 return *this;
113}
114
115template<class Cbc>
116void
117CbcPointer<Cbc>::clear()
118{
119 cbdataReferenceDone(lock); // lock may be nil before and will be nil after
120 cbc = NULL;
121}
122
123template<class Cbc>
124Cbc *
125CbcPointer<Cbc>::raw() const
126{
127 return cbc;
128}
129
130template<class Cbc>
131Cbc *
132CbcPointer<Cbc>::get() const
133{
134 return (lock && cbdataReferenceValid(lock)) ? cbc : NULL;
135}
136
137template<class Cbc>
138Cbc &
139CbcPointer<Cbc>::operator *() const
140{
141 Cbc *c = get();
142 Must(c);
143 return *c;
144}
145
146template<class Cbc>
147Cbc *
148CbcPointer<Cbc>::operator ->() const
149{
150 Cbc *c = get();
151 Must(c);
152 return c;
153}
154
155template <class Cbc>
4cb2536f
A
156std::ostream &CbcPointer<Cbc>::print(std::ostream &os) const
157{
4299f876
AR
158 return os << cbc << '/' << lock;
159}
160
4299f876 161#endif /* SQUID_CBC_POINTER_H */