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