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