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