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