]> git.ipfire.org Git - thirdparty/squid.git/blob - src/CommCalls.h
Merged from trunk
[thirdparty/squid.git] / src / CommCalls.h
1 #ifndef SQUID_COMMCALLS_H
2 #define SQUID_COMMCALLS_H
3
4 #include "base/AsyncCall.h"
5 #include "base/AsyncJobCalls.h"
6 #include "comm_err_t.h"
7 #include "comm/forward.h"
8 #include "MasterXaction.h"
9
10 /* CommCalls implement AsyncCall interface for comm_* callbacks.
11 * The classes cover two call dialer kinds:
12 * - A C-style call using a function pointer (depricated);
13 * - A C++-style call to an AsyncJob child.
14 * and several comm_* callback kinds:
15 * - accept (IOACB)
16 * - connect (CNCB)
17 * - I/O (IOCB)
18 * - timeout (CTCB)
19 * - close (CLCB)
20 * and a special callback kind for passing pipe FD, disk FD or fd_table index 'FD' to the handler:
21 * - FD passing callback (FDECB)
22 */
23
24 class CommAcceptCbParams;
25 typedef void IOACB(const CommAcceptCbParams &params);
26
27 typedef void CNCB(const Comm::ConnectionPointer &conn, comm_err_t status, int xerrno, void *data);
28 typedef void IOCB(const Comm::ConnectionPointer &conn, char *, size_t size, comm_err_t flag, int xerrno, void *data);
29
30 class CommTimeoutCbParams;
31 typedef void CTCB(const CommTimeoutCbParams &params);
32
33 class CommCloseCbParams;
34 typedef void CLCB(const CommCloseCbParams &params);
35
36 class FdeCbParams;
37 typedef void FDECB(const FdeCbParams &params);
38
39 /*
40 * TODO: When there are no function-pointer-based callbacks left, all
41 * this complexity can be removed. Jobs that need comm services will just
42 * implement CommReader, CommWriter, etc. interfaces and receive calls
43 * using general (not comm-specific) AsyncCall code. For now, we have to
44 * allow the caller to create a callback that comm can modify to set
45 * parameters, which is not trivial when the caller type/kind is not
46 * known to comm and there are many kinds of parameters.
47 */
48
49 /* Comm*CbParams classes below handle callback parameters */
50
51 // Maintains parameters common to all comm callbacks
52 class CommCommonCbParams
53 {
54 public:
55 CommCommonCbParams(void *aData);
56 CommCommonCbParams(const CommCommonCbParams &params);
57 ~CommCommonCbParams();
58
59 /// adjust using the current Comm state; returns false to cancel the call
60 // not virtual because callers know dialer type
61 bool syncWithComm() { return true; }
62
63 void print(std::ostream &os) const;
64
65 public:
66 void *data; // cbdata-protected
67
68 /** The connection which this call pertains to.
69 * \itemize On accept() calls this is the new client connection.
70 * \itemize On connect() finished calls this is the newely opened connection.
71 * \itemize On write calls this is the connection just written to.
72 * \itemize On read calls this is the connection just read from.
73 * \itemize On close calls this describes the connection which is now closed.
74 * \itemize On timeouts this is the connection whose operation timed out.
75 * NP: timeouts might also return to the connect/read/write handler with COMM_ERR_TIMEOUT.
76 */
77 Comm::ConnectionPointer conn;
78
79 comm_err_t flag; ///< comm layer result status.
80 int xerrno; ///< The last errno to occur. non-zero if flag is COMM_ERR.
81
82 int fd; ///< FD which the call was about. Set by the async call creator.
83 private:
84 // should not be needed and not yet implemented
85 CommCommonCbParams &operator =(const CommCommonCbParams &params);
86 };
87
88 // accept parameters
89 class CommAcceptCbParams: public CommCommonCbParams
90 {
91 public:
92 CommAcceptCbParams(void *aData);
93
94 void print(std::ostream &os) const;
95
96 /// Transaction which this call is part of.
97 MasterXaction::Pointer xaction;
98 };
99
100 // connect parameters
101 class CommConnectCbParams: public CommCommonCbParams
102 {
103 public:
104 CommConnectCbParams(void *aData);
105
106 bool syncWithComm(); // see CommCommonCbParams::syncWithComm
107 };
108
109 // read/write (I/O) parameters
110 class CommIoCbParams: public CommCommonCbParams
111 {
112 public:
113 CommIoCbParams(void *aData);
114
115 void print(std::ostream &os) const;
116 bool syncWithComm(); // see CommCommonCbParams::syncWithComm
117
118 public:
119 char *buf;
120 size_t size;
121 };
122
123 // close parameters
124 class CommCloseCbParams: public CommCommonCbParams
125 {
126 public:
127 CommCloseCbParams(void *aData);
128 };
129
130 class CommTimeoutCbParams: public CommCommonCbParams
131 {
132 public:
133 CommTimeoutCbParams(void *aData);
134 };
135
136 /// Special Calls parameter, for direct use of an FD without a controlling Comm::Connection
137 /// This is used for pipe() FD with helpers, and internally by Comm when handling some special FD actions.
138 class FdeCbParams: public CommCommonCbParams
139 {
140 public:
141 FdeCbParams(void *aData);
142 // TODO make this a standalone object with FD value and pointer to fde table entry.
143 // that requires all the existing Comm handlers to be updated first though
144 };
145
146 // Interface to expose comm callback parameters of all comm dialers.
147 // GetCommParams() uses this interface to access comm parameters.
148 template <class Params_>
149 class CommDialerParamsT
150 {
151 public:
152 typedef Params_ Params;
153 CommDialerParamsT(const Params &io): params(io) {}
154
155 public:
156 Params params;
157 };
158
159 // Get comm params of an async comm call
160 template <class Params>
161 Params &GetCommParams(AsyncCall::Pointer &call)
162 {
163 typedef CommDialerParamsT<Params> DialerParams;
164 DialerParams *dp = dynamic_cast<DialerParams*>(call->getDialer());
165 assert(dp);
166 return dp->params;
167 }
168
169 // All job dialers with comm parameters are merged into one since they
170 // all have exactly one callback argument and differ in Params type only
171 template <class C, class Params_>
172 class CommCbMemFunT: public JobDialer<C>, public CommDialerParamsT<Params_>
173 {
174 public:
175 typedef Params_ Params;
176 typedef void (C::*Method)(const Params &io);
177
178 CommCbMemFunT(const CbcPointer<C> &aJob, Method aMeth): JobDialer<C>(aJob),
179 CommDialerParamsT<Params_>(aJob.get()),
180 method(aMeth) {}
181
182 virtual bool canDial(AsyncCall &c) {
183 return JobDialer<C>::canDial(c) &&
184 this->params.syncWithComm();
185 }
186
187 virtual void print(std::ostream &os) const {
188 os << '(';
189 this->params.print(os);
190 os << ')';
191 }
192
193 public:
194 Method method;
195
196 protected:
197 virtual void doDial() { ((&(*this->job))->*method)(this->params); }
198 };
199
200 // accept (IOACB) dialer
201 class CommAcceptCbPtrFun: public CallDialer,
202 public CommDialerParamsT<CommAcceptCbParams>
203 {
204 public:
205 typedef CommAcceptCbParams Params;
206 typedef RefCount<CommAcceptCbPtrFun> Pointer;
207
208 CommAcceptCbPtrFun(IOACB *aHandler, const CommAcceptCbParams &aParams);
209 CommAcceptCbPtrFun(const CommAcceptCbPtrFun &o);
210
211 void dial();
212
213 virtual void print(std::ostream &os) const;
214
215 public:
216 IOACB *handler;
217 };
218
219 // connect (CNCB) dialer
220 class CommConnectCbPtrFun: public CallDialer,
221 public CommDialerParamsT<CommConnectCbParams>
222 {
223 public:
224 typedef CommConnectCbParams Params;
225
226 CommConnectCbPtrFun(CNCB *aHandler, const Params &aParams);
227 void dial();
228
229 virtual void print(std::ostream &os) const;
230
231 public:
232 CNCB *handler;
233 };
234
235 // read/write (IOCB) dialer
236 class CommIoCbPtrFun: public CallDialer,
237 public CommDialerParamsT<CommIoCbParams>
238 {
239 public:
240 typedef CommIoCbParams Params;
241
242 CommIoCbPtrFun(IOCB *aHandler, const Params &aParams);
243 void dial();
244
245 virtual void print(std::ostream &os) const;
246
247 public:
248 IOCB *handler;
249 };
250
251 // close (CLCB) dialer
252 class CommCloseCbPtrFun: public CallDialer,
253 public CommDialerParamsT<CommCloseCbParams>
254 {
255 public:
256 typedef CommCloseCbParams Params;
257
258 CommCloseCbPtrFun(CLCB *aHandler, const Params &aParams);
259 void dial();
260
261 virtual void print(std::ostream &os) const;
262
263 public:
264 CLCB *handler;
265 };
266
267 class CommTimeoutCbPtrFun:public CallDialer,
268 public CommDialerParamsT<CommTimeoutCbParams>
269 {
270 public:
271 typedef CommTimeoutCbParams Params;
272
273 CommTimeoutCbPtrFun(CTCB *aHandler, const Params &aParams);
274 void dial();
275
276 virtual void print(std::ostream &os) const;
277
278 public:
279 CTCB *handler;
280 };
281
282 /// FD event (FDECB) dialer
283 class FdeCbPtrFun: public CallDialer,
284 public CommDialerParamsT<FdeCbParams>
285 {
286 public:
287 typedef FdeCbParams Params;
288
289 FdeCbPtrFun(FDECB *aHandler, const Params &aParams);
290 void dial();
291 virtual void print(std::ostream &os) const;
292
293 public:
294 FDECB *handler;
295 };
296
297 // AsyncCall to comm handlers implemented as global functions.
298 // The dialer is one of the Comm*CbPtrFunT above
299 // TODO: Get rid of this class by moving canFire() to canDial() method
300 // of dialers.
301 template <class Dialer>
302 class CommCbFunPtrCallT: public AsyncCall
303 {
304 public:
305 typedef RefCount<CommCbFunPtrCallT<Dialer> > Pointer;
306 typedef typename Dialer::Params Params;
307
308 inline CommCbFunPtrCallT(int debugSection, int debugLevel,
309 const char *callName, const Dialer &aDialer);
310
311 inline CommCbFunPtrCallT(const CommCbFunPtrCallT &o) :
312 AsyncCall(o.debugSection, o.debugLevel, o.name),
313 dialer(o.dialer) {}
314
315 ~CommCbFunPtrCallT() {}
316
317 virtual CallDialer* getDialer() { return &dialer; }
318
319 public:
320 Dialer dialer;
321
322 protected:
323 inline virtual bool canFire();
324 inline virtual void fire();
325
326 private:
327 CommCbFunPtrCallT & operator=(const CommCbFunPtrCallT &); // not defined. not permitted.
328 };
329
330 // Conveninece wrapper: It is often easier to call a templated function than
331 // to create a templated class.
332 template <class Dialer>
333 inline
334 CommCbFunPtrCallT<Dialer> *commCbCall(int debugSection, int debugLevel,
335 const char *callName, const Dialer &dialer)
336 {
337 return new CommCbFunPtrCallT<Dialer>(debugSection, debugLevel, callName,
338 dialer);
339 }
340
341 /* inlined implementation of templated methods */
342
343 /* CommCbFunPtrCallT */
344
345 template <class Dialer>
346 CommCbFunPtrCallT<Dialer>::CommCbFunPtrCallT(int aDebugSection, int aDebugLevel,
347 const char *callName, const Dialer &aDialer):
348 AsyncCall(aDebugSection, aDebugLevel, callName),
349 dialer(aDialer)
350 {
351 }
352
353 template <class Dialer>
354 bool
355 CommCbFunPtrCallT<Dialer>::canFire()
356 {
357 if (!AsyncCall::canFire())
358 return false;
359
360 if (!cbdataReferenceValid(dialer.params.data))
361 return cancel("callee gone");
362
363 if (!dialer.params.syncWithComm())
364 return cancel("out of sync w/comm");
365
366 if (!dialer.handler)
367 return cancel("no callback requested");
368
369 return true;
370 }
371
372 template <class Dialer>
373 void
374 CommCbFunPtrCallT<Dialer>::fire()
375 {
376 dialer.dial();
377 }
378
379 #endif /* SQUID_COMMCALLS_H */