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