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