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