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