]> git.ipfire.org Git - thirdparty/squid.git/blob - src/CommCalls.h
SourceFormat: enforcement
[thirdparty/squid.git] / src / CommCalls.h
1
2 /*
3 * $Id$
4 */
5
6 #ifndef SQUID_COMMCALLS_H
7 #define SQUID_COMMCALLS_H
8
9 #include "comm.h"
10 #include "ConnectionDetail.h"
11 #include "DnsLookupDetails.h"
12 #include "base/AsyncCall.h"
13 #include "base/AsyncJobCalls.h"
14
15 /* CommCalls implement AsyncCall interface for comm_* callbacks.
16 * The classes cover two call dialer kinds:
17 * - A C-style call using a function pointer (depricated);
18 * - A C++-style call to an AsyncJob child.
19 * and three comm_* callback kinds:
20 * - accept (IOACB),
21 * - connect (CNCB),
22 * - I/O (IOCB).
23 */
24
25 /*
26 * TODO: When there are no function-pointer-based callbacks left, all
27 * this complexity can be removed. Jobs that need comm services will just
28 * implement CommReader, CommWriter, etc. interfaces and receive calls
29 * using general (not comm-specific) AsyncCall code. For now, we have to
30 * allow the caller to create a callback that comm can modify to set
31 * parameters, which is not trivial when the caller type/kind is not
32 * known to comm and there are many kinds of parameters.
33 */
34
35
36 /* Comm*CbParams classes below handle callback parameters */
37
38 // Maintains parameters common to all comm callbacks
39 class CommCommonCbParams
40 {
41 public:
42 CommCommonCbParams(void *aData);
43 CommCommonCbParams(const CommCommonCbParams &params);
44 ~CommCommonCbParams();
45
46 /// adjust using the current Comm state; returns false to cancel the call
47 // not virtual because callers know dialer type
48 bool syncWithComm() { return true; }
49
50 void print(std::ostream &os) const;
51
52 public:
53 void *data; // cbdata-protected
54 int fd;
55 int xerrno;
56 comm_err_t flag;
57
58 private:
59 // should not be needed and not yet implemented
60 CommCommonCbParams &operator =(const CommCommonCbParams &params);
61 };
62
63 // accept parameters
64 class CommAcceptCbParams: public CommCommonCbParams
65 {
66 public:
67 CommAcceptCbParams(void *aData);
68
69 void print(std::ostream &os) const;
70
71 public:
72 ConnectionDetail details;
73 int nfd; // TODO: rename to fdNew or somesuch
74 };
75
76 // connect parameters
77 class CommConnectCbParams: public CommCommonCbParams
78 {
79 public:
80 CommConnectCbParams(void *aData);
81
82 bool syncWithComm(); // see CommCommonCbParams::syncWithComm
83
84 void print(std::ostream &os) const;
85
86 public:
87 DnsLookupDetails dns;
88 };
89
90 // read/write (I/O) parameters
91 class CommIoCbParams: public CommCommonCbParams
92 {
93 public:
94 CommIoCbParams(void *aData);
95
96 void print(std::ostream &os) const;
97 bool syncWithComm(); // see CommCommonCbParams::syncWithComm
98
99 public:
100 char *buf;
101 size_t size;
102 };
103
104 // close parameters
105 class CommCloseCbParams: public CommCommonCbParams
106 {
107 public:
108 CommCloseCbParams(void *aData);
109 };
110
111 class CommTimeoutCbParams: public CommCommonCbParams
112 {
113 public:
114 CommTimeoutCbParams(void *aData);
115 };
116
117 // Interface to expose comm callback parameters of all comm dialers.
118 // GetCommParams() uses this interface to access comm parameters.
119 template <class Params_>
120 class CommDialerParamsT
121 {
122 public:
123 typedef Params_ Params;
124 CommDialerParamsT(const Params &io): params(io) {}
125
126 public:
127 Params params;
128 };
129
130 // Get comm params of an async comm call
131 template <class Params>
132 Params &GetCommParams(AsyncCall::Pointer &call)
133 {
134 typedef CommDialerParamsT<Params> DialerParams;
135 DialerParams *dp = dynamic_cast<DialerParams*>(call->getDialer());
136 assert(dp);
137 return dp->params;
138 }
139
140
141 // All job dialers with comm parameters are merged into one since they
142 // all have exactly one callback argument and differ in Params type only
143 template <class C, class Params_>
144 class CommCbMemFunT: public JobDialer, public CommDialerParamsT<Params_>
145 {
146 public:
147 typedef Params_ Params;
148 typedef void (C::*Method)(const Params &io);
149
150 CommCbMemFunT(C *obj, Method meth): JobDialer(obj),
151 CommDialerParamsT<Params>(obj), object(obj), method(meth) {}
152
153 virtual bool canDial(AsyncCall &c) {
154 return JobDialer::canDial(c) &&
155 this->params.syncWithComm();
156 }
157
158 virtual void print(std::ostream &os) const {
159 os << '(';
160 this->params.print(os);
161 os << ')';
162 }
163
164 public:
165 C *object;
166 Method method;
167
168 protected:
169 virtual void doDial() { (object->*method)(this->params); }
170 };
171
172
173 // accept (IOACB) dialer
174 class CommAcceptCbPtrFun: public CallDialer,
175 public CommDialerParamsT<CommAcceptCbParams>
176 {
177 public:
178 typedef CommAcceptCbParams Params;
179
180 CommAcceptCbPtrFun(IOACB *aHandler, const CommAcceptCbParams &aParams);
181 void dial();
182
183 virtual void print(std::ostream &os) const;
184
185 public:
186 IOACB *handler;
187 };
188
189 // connect (CNCB) dialer
190 class CommConnectCbPtrFun: public CallDialer,
191 public CommDialerParamsT<CommConnectCbParams>
192 {
193 public:
194 typedef CommConnectCbParams Params;
195
196 CommConnectCbPtrFun(CNCB *aHandler, const Params &aParams);
197 void dial();
198
199 virtual void print(std::ostream &os) const;
200
201 public:
202 CNCB *handler;
203 };
204
205
206 // read/write (IOCB) dialer
207 class CommIoCbPtrFun: public CallDialer,
208 public CommDialerParamsT<CommIoCbParams>
209 {
210 public:
211 typedef CommIoCbParams Params;
212
213 CommIoCbPtrFun(IOCB *aHandler, const Params &aParams);
214 void dial();
215
216 virtual void print(std::ostream &os) const;
217
218 public:
219 IOCB *handler;
220 };
221
222
223 // close (PF) dialer
224 class CommCloseCbPtrFun: public CallDialer,
225 public CommDialerParamsT<CommCloseCbParams>
226 {
227 public:
228 typedef CommCloseCbParams Params;
229
230 CommCloseCbPtrFun(PF *aHandler, const Params &aParams);
231 void dial();
232
233 virtual void print(std::ostream &os) const;
234
235 public:
236 PF *handler;
237 };
238
239 class CommTimeoutCbPtrFun:public CallDialer,
240 public CommDialerParamsT<CommTimeoutCbParams>
241 {
242 public:
243 typedef CommTimeoutCbParams Params;
244
245 CommTimeoutCbPtrFun(PF *aHandler, const Params &aParams);
246 void dial();
247
248 virtual void print(std::ostream &os) const;
249
250 public:
251 PF *handler;
252 };
253
254 // AsyncCall to comm handlers implemented as global functions.
255 // The dialer is one of the Comm*CbPtrFunT above
256 // TODO: Get rid of this class by moving canFire() to canDial() method
257 // of dialers.
258 template <class Dialer>
259 class CommCbFunPtrCallT: public AsyncCall
260 {
261 public:
262 typedef typename Dialer::Params Params;
263
264 inline CommCbFunPtrCallT(int debugSection, int debugLevel,
265 const char *callName, const Dialer &aDialer);
266
267 virtual CallDialer* getDialer() { return &dialer; }
268
269 public:
270 Dialer dialer;
271
272 protected:
273 inline virtual bool canFire();
274 inline virtual void fire();
275 };
276
277 // Conveninece wrapper: It is often easier to call a templated function than
278 // to create a templated class.
279 template <class Dialer>
280 inline
281 CommCbFunPtrCallT<Dialer> *commCbCall(int debugSection, int debugLevel,
282 const char *callName, const Dialer &dialer)
283 {
284 return new CommCbFunPtrCallT<Dialer>(debugSection, debugLevel, callName,
285 dialer);
286 }
287
288 /* inlined implementation of templated methods */
289
290 /* CommCbFunPtrCallT */
291
292 template <class Dialer>
293 CommCbFunPtrCallT<Dialer>::CommCbFunPtrCallT(int debugSection, int debugLevel,
294 const char *callName, const Dialer &aDialer):
295 AsyncCall(debugSection, debugLevel, callName),
296 dialer(aDialer)
297 {
298 }
299
300
301 template <class Dialer>
302 bool
303 CommCbFunPtrCallT<Dialer>::canFire()
304 {
305 if (!AsyncCall::canFire())
306 return false;
307
308 if (!cbdataReferenceValid(dialer.params.data))
309 return cancel("callee gone");
310
311 if (!dialer.params.syncWithComm())
312 return cancel("out of sync w/comm");
313
314 return true;
315 }
316
317 template <class Dialer>
318 void
319 CommCbFunPtrCallT<Dialer>::fire()
320 {
321 dialer.dial();
322 }
323
324 #endif /* SQUID_COMMCALLS_H */