]> git.ipfire.org Git - thirdparty/squid.git/blob - src/CommCalls.h
Polish up the diff
[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/forward.h"
7 #include "comm_err_t.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 * - On accept() calls this is the new client connection.
70 * - On connect() finished calls this is the newely opened connection.
71 * - On write calls this is the connection just written to.
72 * - On read calls this is the connection just read from.
73 * - On close calls this describes the connection which is now closed.
74 * - 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 class SBuf;
110
111 // read/write (I/O) parameters
112 class CommIoCbParams: public CommCommonCbParams
113 {
114 public:
115 CommIoCbParams(void *aData);
116
117 void print(std::ostream &os) const;
118 bool syncWithComm(); // see CommCommonCbParams::syncWithComm
119
120 public:
121 char *buf;
122 size_t size;
123 SBuf *buf2; // alternative buffer for use when buf is unset
124 };
125
126 // close parameters
127 class CommCloseCbParams: public CommCommonCbParams
128 {
129 public:
130 CommCloseCbParams(void *aData);
131 };
132
133 class CommTimeoutCbParams: public CommCommonCbParams
134 {
135 public:
136 CommTimeoutCbParams(void *aData);
137 };
138
139 /// Special Calls parameter, for direct use of an FD without a controlling Comm::Connection
140 /// This is used for pipe() FD with helpers, and internally by Comm when handling some special FD actions.
141 class FdeCbParams: public CommCommonCbParams
142 {
143 public:
144 FdeCbParams(void *aData);
145 // TODO make this a standalone object with FD value and pointer to fde table entry.
146 // that requires all the existing Comm handlers to be updated first though
147 };
148
149 // Interface to expose comm callback parameters of all comm dialers.
150 // GetCommParams() uses this interface to access comm parameters.
151 template <class Params_>
152 class CommDialerParamsT
153 {
154 public:
155 typedef Params_ Params;
156 CommDialerParamsT(const Params &io): params(io) {}
157
158 public:
159 Params params;
160 };
161
162 // Get comm params of an async comm call
163 template <class Params>
164 Params &GetCommParams(AsyncCall::Pointer &call)
165 {
166 typedef CommDialerParamsT<Params> DialerParams;
167 DialerParams *dp = dynamic_cast<DialerParams*>(call->getDialer());
168 assert(dp);
169 return dp->params;
170 }
171
172 // All job dialers with comm parameters are merged into one since they
173 // all have exactly one callback argument and differ in Params type only
174 template <class C, class Params_>
175 class CommCbMemFunT: public JobDialer<C>, public CommDialerParamsT<Params_>
176 {
177 public:
178 typedef Params_ Params;
179 typedef void (C::*Method)(const Params &io);
180
181 CommCbMemFunT(const CbcPointer<C> &aJob, Method aMeth): JobDialer<C>(aJob),
182 CommDialerParamsT<Params_>(aJob->toCbdata()),
183 method(aMeth) {}
184
185 virtual bool canDial(AsyncCall &c) {
186 return JobDialer<C>::canDial(c) &&
187 this->params.syncWithComm();
188 }
189
190 virtual void print(std::ostream &os) const {
191 os << '(';
192 this->params.print(os);
193 os << ')';
194 }
195
196 public:
197 Method method;
198
199 protected:
200 virtual void doDial() { ((&(*this->job))->*method)(this->params); }
201 };
202
203 // accept (IOACB) dialer
204 class CommAcceptCbPtrFun: public CallDialer,
205 public CommDialerParamsT<CommAcceptCbParams>
206 {
207 public:
208 typedef CommAcceptCbParams Params;
209 typedef RefCount<CommAcceptCbPtrFun> Pointer;
210
211 CommAcceptCbPtrFun(IOACB *aHandler, const CommAcceptCbParams &aParams);
212 CommAcceptCbPtrFun(const CommAcceptCbPtrFun &o);
213
214 void dial();
215
216 virtual void print(std::ostream &os) const;
217
218 public:
219 IOACB *handler;
220 };
221
222 // connect (CNCB) dialer
223 class CommConnectCbPtrFun: public CallDialer,
224 public CommDialerParamsT<CommConnectCbParams>
225 {
226 public:
227 typedef CommConnectCbParams Params;
228
229 CommConnectCbPtrFun(CNCB *aHandler, const Params &aParams);
230 void dial();
231
232 virtual void print(std::ostream &os) const;
233
234 public:
235 CNCB *handler;
236 };
237
238 // read/write (IOCB) dialer
239 class CommIoCbPtrFun: public CallDialer,
240 public CommDialerParamsT<CommIoCbParams>
241 {
242 public:
243 typedef CommIoCbParams Params;
244
245 CommIoCbPtrFun(IOCB *aHandler, const Params &aParams);
246 void dial();
247
248 virtual void print(std::ostream &os) const;
249
250 public:
251 IOCB *handler;
252 };
253
254 // close (CLCB) dialer
255 class CommCloseCbPtrFun: public CallDialer,
256 public CommDialerParamsT<CommCloseCbParams>
257 {
258 public:
259 typedef CommCloseCbParams Params;
260
261 CommCloseCbPtrFun(CLCB *aHandler, const Params &aParams);
262 void dial();
263
264 virtual void print(std::ostream &os) const;
265
266 public:
267 CLCB *handler;
268 };
269
270 class CommTimeoutCbPtrFun:public CallDialer,
271 public CommDialerParamsT<CommTimeoutCbParams>
272 {
273 public:
274 typedef CommTimeoutCbParams Params;
275
276 CommTimeoutCbPtrFun(CTCB *aHandler, const Params &aParams);
277 void dial();
278
279 virtual void print(std::ostream &os) const;
280
281 public:
282 CTCB *handler;
283 };
284
285 /// FD event (FDECB) dialer
286 class FdeCbPtrFun: public CallDialer,
287 public CommDialerParamsT<FdeCbParams>
288 {
289 public:
290 typedef FdeCbParams Params;
291
292 FdeCbPtrFun(FDECB *aHandler, const Params &aParams);
293 void dial();
294 virtual void print(std::ostream &os) const;
295
296 public:
297 FDECB *handler;
298 };
299
300 // AsyncCall to comm handlers implemented as global functions.
301 // The dialer is one of the Comm*CbPtrFunT above
302 // TODO: Get rid of this class by moving canFire() to canDial() method
303 // of dialers.
304 template <class Dialer>
305 class CommCbFunPtrCallT: public AsyncCall
306 {
307 public:
308 typedef RefCount<CommCbFunPtrCallT<Dialer> > Pointer;
309 typedef typename Dialer::Params Params;
310
311 inline CommCbFunPtrCallT(int debugSection, int debugLevel,
312 const char *callName, const Dialer &aDialer);
313
314 inline CommCbFunPtrCallT(const CommCbFunPtrCallT &o) :
315 AsyncCall(o.debugSection, o.debugLevel, o.name),
316 dialer(o.dialer) {}
317
318 ~CommCbFunPtrCallT() {}
319
320 virtual CallDialer* getDialer() { return &dialer; }
321
322 public:
323 Dialer dialer;
324
325 protected:
326 inline virtual bool canFire();
327 inline virtual void fire();
328
329 private:
330 CommCbFunPtrCallT & operator=(const CommCbFunPtrCallT &); // not defined. not permitted.
331 };
332
333 // Conveninece wrapper: It is often easier to call a templated function than
334 // to create a templated class.
335 template <class Dialer>
336 inline
337 CommCbFunPtrCallT<Dialer> *commCbCall(int debugSection, int debugLevel,
338 const char *callName, const Dialer &dialer)
339 {
340 return new CommCbFunPtrCallT<Dialer>(debugSection, debugLevel, callName,
341 dialer);
342 }
343
344 /* inlined implementation of templated methods */
345
346 /* CommCbFunPtrCallT */
347
348 template <class Dialer>
349 CommCbFunPtrCallT<Dialer>::CommCbFunPtrCallT(int aDebugSection, int aDebugLevel,
350 const char *callName, const Dialer &aDialer):
351 AsyncCall(aDebugSection, aDebugLevel, callName),
352 dialer(aDialer)
353 {
354 }
355
356 template <class Dialer>
357 bool
358 CommCbFunPtrCallT<Dialer>::canFire()
359 {
360 if (!AsyncCall::canFire())
361 return false;
362
363 if (!cbdataReferenceValid(dialer.params.data))
364 return cancel("callee gone");
365
366 if (!dialer.params.syncWithComm())
367 return cancel("out of sync w/comm");
368
369 if (!dialer.handler)
370 return cancel("no callback requested");
371
372 return true;
373 }
374
375 template <class Dialer>
376 void
377 CommCbFunPtrCallT<Dialer>::fire()
378 {
379 dialer.dial();
380 }
381
382 #endif /* SQUID_COMMCALLS_H */