]>
Commit | Line | Data |
---|---|---|
b0469965 | 1 | #ifndef SQUID_COMMCALLS_H |
2 | #define SQUID_COMMCALLS_H | |
3 | ||
882255af AR |
4 | #include "base/AsyncCall.h" |
5 | #include "base/AsyncJobCalls.h" | |
f9b72e0c | 6 | #include "comm/forward.h" |
602d9612 | 7 | #include "comm_err_t.h" |
94bfd31f | 8 | #include "MasterXaction.h" |
b0469965 | 9 | |
10 | /* CommCalls implement AsyncCall interface for comm_* callbacks. | |
11 | * The classes cover two call dialer kinds: | |
12 | * - A C-style call using a function pointer (depricated); | |
13 | * - A C++-style call to an AsyncJob child. | |
8d77a37c AJ |
14 | * and several comm_* callback kinds: |
15 | * - accept (IOACB) | |
16 | * - connect (CNCB) | |
17 | * - I/O (IOCB) | |
18 | * - timeout (CTCB) | |
575d05c4 | 19 | * - close (CLCB) |
a17bf806 AJ |
20 | * and a special callback kind for passing pipe FD, disk FD or fd_table index 'FD' to the handler: |
21 | * - FD passing callback (FDECB) | |
b0469965 | 22 | */ |
23 | ||
449f0115 AJ |
24 | class CommAcceptCbParams; |
25 | typedef void IOACB(const CommAcceptCbParams ¶ms); | |
26 | ||
f01d4b80 | 27 | typedef void CNCB(const Comm::ConnectionPointer &conn, comm_err_t status, int xerrno, void *data); |
a138c8fc | 28 | typedef void IOCB(const Comm::ConnectionPointer &conn, char *, size_t size, comm_err_t flag, int xerrno, void *data); |
f9b72e0c | 29 | |
8d77a37c AJ |
30 | class CommTimeoutCbParams; |
31 | typedef void CTCB(const CommTimeoutCbParams ¶ms); | |
32 | ||
575d05c4 AJ |
33 | class CommCloseCbParams; |
34 | typedef void CLCB(const CommCloseCbParams ¶ms); | |
35 | ||
a17bf806 AJ |
36 | class FdeCbParams; |
37 | typedef void FDECB(const FdeCbParams ¶ms); | |
38 | ||
26ac0430 AJ |
39 | /* |
40 | * TODO: When there are no function-pointer-based callbacks left, all | |
41 | * this complexity can be removed. Jobs that need comm services will just | |
42 | * implement CommReader, CommWriter, etc. interfaces and receive calls | |
43 | * using general (not comm-specific) AsyncCall code. For now, we have to | |
44 | * allow the caller to create a callback that comm can modify to set | |
45 | * parameters, which is not trivial when the caller type/kind is not | |
46 | * known to comm and there are many kinds of parameters. | |
47 | */ | |
b0469965 | 48 | |
b0469965 | 49 | /* Comm*CbParams classes below handle callback parameters */ |
50 | ||
51 | // Maintains parameters common to all comm callbacks | |
26ac0430 AJ |
52 | class CommCommonCbParams |
53 | { | |
b0469965 | 54 | public: |
55 | CommCommonCbParams(void *aData); | |
56 | CommCommonCbParams(const CommCommonCbParams ¶ms); | |
57 | ~CommCommonCbParams(); | |
58 | ||
4c3ba68d AR |
59 | /// adjust using the current Comm state; returns false to cancel the call |
60 | // not virtual because callers know dialer type | |
26ac0430 | 61 | bool syncWithComm() { return true; } |
82ec8dfc | 62 | |
b0469965 | 63 | void print(std::ostream &os) const; |
64 | ||
65 | public: | |
66 | void *data; // cbdata-protected | |
3e4bebf8 AJ |
67 | |
68 | /** The connection which this call pertains to. | |
d6d0eb11 AJ |
69 | * - On accept() calls this is the new client connection. |
70 | * - On connect() finished calls this is the newely opened connection. | |
71 | * - On write calls this is the connection just written to. | |
72 | * - On read calls this is the connection just read from. | |
73 | * - On close calls this describes the connection which is now closed. | |
74 | * - On timeouts this is the connection whose operation timed out. | |
75 | * + NP: timeouts might also return to the connect/read/write handler with COMM_ERR_TIMEOUT. | |
3e4bebf8 | 76 | */ |
7957e704 | 77 | Comm::ConnectionPointer conn; |
b0469965 | 78 | |
3e4bebf8 AJ |
79 | comm_err_t flag; ///< comm layer result status. |
80 | int xerrno; ///< The last errno to occur. non-zero if flag is COMM_ERR. | |
81 | ||
a17bf806 | 82 | int fd; ///< FD which the call was about. Set by the async call creator. |
b0469965 | 83 | private: |
84 | // should not be needed and not yet implemented | |
26ac0430 | 85 | CommCommonCbParams &operator =(const CommCommonCbParams ¶ms); |
b0469965 | 86 | }; |
87 | ||
88 | // accept parameters | |
26ac0430 AJ |
89 | class CommAcceptCbParams: public CommCommonCbParams |
90 | { | |
b0469965 | 91 | public: |
92 | CommAcceptCbParams(void *aData); | |
94bfd31f AJ |
93 | |
94 | void print(std::ostream &os) const; | |
95 | ||
96 | /// Transaction which this call is part of. | |
97 | MasterXaction::Pointer xaction; | |
b0469965 | 98 | }; |
99 | ||
100 | // connect parameters | |
26ac0430 AJ |
101 | class CommConnectCbParams: public CommCommonCbParams |
102 | { | |
b0469965 | 103 | public: |
104 | CommConnectCbParams(void *aData); | |
4c3ba68d AR |
105 | |
106 | bool syncWithComm(); // see CommCommonCbParams::syncWithComm | |
b0469965 | 107 | }; |
108 | ||
109 | // read/write (I/O) parameters | |
26ac0430 AJ |
110 | class CommIoCbParams: public CommCommonCbParams |
111 | { | |
b0469965 | 112 | public: |
113 | CommIoCbParams(void *aData); | |
114 | ||
115 | void print(std::ostream &os) const; | |
4c3ba68d | 116 | bool syncWithComm(); // see CommCommonCbParams::syncWithComm |
b0469965 | 117 | |
118 | public: | |
119 | char *buf; | |
120 | size_t size; | |
121 | }; | |
122 | ||
123 | // close parameters | |
26ac0430 AJ |
124 | class CommCloseCbParams: public CommCommonCbParams |
125 | { | |
b0469965 | 126 | public: |
127 | CommCloseCbParams(void *aData); | |
128 | }; | |
129 | ||
26ac0430 AJ |
130 | class CommTimeoutCbParams: public CommCommonCbParams |
131 | { | |
b0469965 | 132 | public: |
133 | CommTimeoutCbParams(void *aData); | |
134 | }; | |
135 | ||
a17bf806 AJ |
136 | /// Special Calls parameter, for direct use of an FD without a controlling Comm::Connection |
137 | /// This is used for pipe() FD with helpers, and internally by Comm when handling some special FD actions. | |
138 | class FdeCbParams: public CommCommonCbParams | |
139 | { | |
140 | public: | |
141 | FdeCbParams(void *aData); | |
142 | // TODO make this a standalone object with FD value and pointer to fde table entry. | |
143 | // that requires all the existing Comm handlers to be updated first though | |
144 | }; | |
145 | ||
b0469965 | 146 | // Interface to expose comm callback parameters of all comm dialers. |
147 | // GetCommParams() uses this interface to access comm parameters. | |
148 | template <class Params_> | |
26ac0430 AJ |
149 | class CommDialerParamsT |
150 | { | |
b0469965 | 151 | public: |
152 | typedef Params_ Params; | |
153 | CommDialerParamsT(const Params &io): params(io) {} | |
154 | ||
155 | public: | |
156 | Params params; | |
157 | }; | |
158 | ||
159 | // Get comm params of an async comm call | |
160 | template <class Params> | |
26ac0430 AJ |
161 | Params &GetCommParams(AsyncCall::Pointer &call) |
162 | { | |
163 | typedef CommDialerParamsT<Params> DialerParams; | |
b0469965 | 164 | DialerParams *dp = dynamic_cast<DialerParams*>(call->getDialer()); |
165 | assert(dp); | |
166 | return dp->params; | |
167 | } | |
168 | ||
b0469965 | 169 | // All job dialers with comm parameters are merged into one since they |
170 | // all have exactly one callback argument and differ in Params type only | |
171 | template <class C, class Params_> | |
4299f876 | 172 | class CommCbMemFunT: public JobDialer<C>, public CommDialerParamsT<Params_> |
b0469965 | 173 | { |
174 | public: | |
175 | typedef Params_ Params; | |
176 | typedef void (C::*Method)(const Params &io); | |
177 | ||
5f621cd0 | 178 | CommCbMemFunT(const CbcPointer<C> &aJob, Method aMeth): JobDialer<C>(aJob), |
9fed6779 | 179 | CommDialerParamsT<Params_>(aJob->toCbdata()), |
5f621cd0 | 180 | method(aMeth) {} |
b0469965 | 181 | |
26ac0430 | 182 | virtual bool canDial(AsyncCall &c) { |
4299f876 | 183 | return JobDialer<C>::canDial(c) && |
26ac0430 AJ |
184 | this->params.syncWithComm(); |
185 | } | |
4c3ba68d | 186 | |
b0469965 | 187 | virtual void print(std::ostream &os) const { |
26ac0430 AJ |
188 | os << '('; |
189 | this->params.print(os); | |
190 | os << ')'; | |
191 | } | |
b0469965 | 192 | |
193 | public: | |
b0469965 | 194 | Method method; |
195 | ||
196 | protected: | |
4299f876 | 197 | virtual void doDial() { ((&(*this->job))->*method)(this->params); } |
b0469965 | 198 | }; |
199 | ||
b0469965 | 200 | // accept (IOACB) dialer |
201 | class CommAcceptCbPtrFun: public CallDialer, | |
e1381638 | 202 | public CommDialerParamsT<CommAcceptCbParams> |
b0469965 | 203 | { |
204 | public: | |
205 | typedef CommAcceptCbParams Params; | |
b9ddfca2 | 206 | typedef RefCount<CommAcceptCbPtrFun> Pointer; |
b0469965 | 207 | |
208 | CommAcceptCbPtrFun(IOACB *aHandler, const CommAcceptCbParams &aParams); | |
b9ddfca2 | 209 | CommAcceptCbPtrFun(const CommAcceptCbPtrFun &o); |
b0469965 | 210 | |
b9ddfca2 | 211 | void dial(); |
80463bb4 | 212 | |
b0469965 | 213 | virtual void print(std::ostream &os) const; |
214 | ||
215 | public: | |
216 | IOACB *handler; | |
217 | }; | |
218 | ||
219 | // connect (CNCB) dialer | |
220 | class CommConnectCbPtrFun: public CallDialer, | |
e1381638 | 221 | public CommDialerParamsT<CommConnectCbParams> |
b0469965 | 222 | { |
223 | public: | |
224 | typedef CommConnectCbParams Params; | |
225 | ||
226 | CommConnectCbPtrFun(CNCB *aHandler, const Params &aParams); | |
227 | void dial(); | |
228 | ||
229 | virtual void print(std::ostream &os) const; | |
230 | ||
231 | public: | |
232 | CNCB *handler; | |
233 | }; | |
234 | ||
b0469965 | 235 | // read/write (IOCB) dialer |
236 | class CommIoCbPtrFun: public CallDialer, | |
e1381638 | 237 | public CommDialerParamsT<CommIoCbParams> |
b0469965 | 238 | { |
239 | public: | |
240 | typedef CommIoCbParams Params; | |
241 | ||
242 | CommIoCbPtrFun(IOCB *aHandler, const Params &aParams); | |
243 | void dial(); | |
244 | ||
245 | virtual void print(std::ostream &os) const; | |
246 | ||
247 | public: | |
248 | IOCB *handler; | |
249 | }; | |
250 | ||
575d05c4 | 251 | // close (CLCB) dialer |
b0469965 | 252 | class CommCloseCbPtrFun: public CallDialer, |
e1381638 | 253 | public CommDialerParamsT<CommCloseCbParams> |
b0469965 | 254 | { |
255 | public: | |
256 | typedef CommCloseCbParams Params; | |
257 | ||
575d05c4 | 258 | CommCloseCbPtrFun(CLCB *aHandler, const Params &aParams); |
b0469965 | 259 | void dial(); |
260 | ||
261 | virtual void print(std::ostream &os) const; | |
262 | ||
263 | public: | |
575d05c4 | 264 | CLCB *handler; |
b0469965 | 265 | }; |
266 | ||
267 | class CommTimeoutCbPtrFun:public CallDialer, | |
e1381638 | 268 | public CommDialerParamsT<CommTimeoutCbParams> |
b0469965 | 269 | { |
270 | public: | |
271 | typedef CommTimeoutCbParams Params; | |
272 | ||
8d77a37c | 273 | CommTimeoutCbPtrFun(CTCB *aHandler, const Params &aParams); |
b0469965 | 274 | void dial(); |
275 | ||
276 | virtual void print(std::ostream &os) const; | |
277 | ||
278 | public: | |
8d77a37c | 279 | CTCB *handler; |
b0469965 | 280 | }; |
281 | ||
a17bf806 AJ |
282 | /// FD event (FDECB) dialer |
283 | class FdeCbPtrFun: public CallDialer, | |
284 | public CommDialerParamsT<FdeCbParams> | |
285 | { | |
286 | public: | |
287 | typedef FdeCbParams Params; | |
288 | ||
289 | FdeCbPtrFun(FDECB *aHandler, const Params &aParams); | |
290 | void dial(); | |
291 | virtual void print(std::ostream &os) const; | |
292 | ||
293 | public: | |
294 | FDECB *handler; | |
295 | }; | |
296 | ||
b0469965 | 297 | // AsyncCall to comm handlers implemented as global functions. |
298 | // The dialer is one of the Comm*CbPtrFunT above | |
299 | // TODO: Get rid of this class by moving canFire() to canDial() method | |
300 | // of dialers. | |
301 | template <class Dialer> | |
26ac0430 AJ |
302 | class CommCbFunPtrCallT: public AsyncCall |
303 | { | |
b0469965 | 304 | public: |
b9ddfca2 | 305 | typedef RefCount<CommCbFunPtrCallT<Dialer> > Pointer; |
b0469965 | 306 | typedef typename Dialer::Params Params; |
307 | ||
308 | inline CommCbFunPtrCallT(int debugSection, int debugLevel, | |
26ac0430 | 309 | const char *callName, const Dialer &aDialer); |
b0469965 | 310 | |
cbff89ba AJ |
311 | inline CommCbFunPtrCallT(const CommCbFunPtrCallT &o) : |
312 | AsyncCall(o.debugSection, o.debugLevel, o.name), | |
db98b2bd | 313 | dialer(o.dialer) {} |
cbff89ba AJ |
314 | |
315 | ~CommCbFunPtrCallT() {} | |
b9ddfca2 | 316 | |
b0469965 | 317 | virtual CallDialer* getDialer() { return &dialer; } |
318 | ||
319 | public: | |
320 | Dialer dialer; | |
321 | ||
322 | protected: | |
323 | inline virtual bool canFire(); | |
324 | inline virtual void fire(); | |
cbff89ba AJ |
325 | |
326 | private: | |
327 | CommCbFunPtrCallT & operator=(const CommCbFunPtrCallT &); // not defined. not permitted. | |
b0469965 | 328 | }; |
329 | ||
330 | // Conveninece wrapper: It is often easier to call a templated function than | |
331 | // to create a templated class. | |
332 | template <class Dialer> | |
333 | inline | |
334 | CommCbFunPtrCallT<Dialer> *commCbCall(int debugSection, int debugLevel, | |
26ac0430 | 335 | const char *callName, const Dialer &dialer) |
b0469965 | 336 | { |
337 | return new CommCbFunPtrCallT<Dialer>(debugSection, debugLevel, callName, | |
26ac0430 | 338 | dialer); |
b0469965 | 339 | } |
340 | ||
341 | /* inlined implementation of templated methods */ | |
342 | ||
343 | /* CommCbFunPtrCallT */ | |
344 | ||
345 | template <class Dialer> | |
18ec8500 | 346 | CommCbFunPtrCallT<Dialer>::CommCbFunPtrCallT(int aDebugSection, int aDebugLevel, |
26ac0430 | 347 | const char *callName, const Dialer &aDialer): |
18ec8500 | 348 | AsyncCall(aDebugSection, aDebugLevel, callName), |
b0469965 | 349 | dialer(aDialer) |
350 | { | |
351 | } | |
352 | ||
b0469965 | 353 | template <class Dialer> |
354 | bool | |
355 | CommCbFunPtrCallT<Dialer>::canFire() | |
356 | { | |
357 | if (!AsyncCall::canFire()) | |
358 | return false; | |
359 | ||
360 | if (!cbdataReferenceValid(dialer.params.data)) | |
361 | return cancel("callee gone"); | |
362 | ||
4c3ba68d AR |
363 | if (!dialer.params.syncWithComm()) |
364 | return cancel("out of sync w/comm"); | |
365 | ||
870cec0a AR |
366 | if (!dialer.handler) |
367 | return cancel("no callback requested"); | |
368 | ||
b0469965 | 369 | return true; |
370 | } | |
371 | ||
372 | template <class Dialer> | |
373 | void | |
374 | CommCbFunPtrCallT<Dialer>::fire() | |
375 | { | |
376 | dialer.dial(); | |
377 | } | |
378 | ||
379 | #endif /* SQUID_COMMCALLS_H */ |