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