]> git.ipfire.org Git - thirdparty/squid.git/blob - src/CommCalls.h
Maintenance: automate header guards 2/3 (#1655)
[thirdparty/squid.git] / src / CommCalls.h
1 /*
2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
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
9 #ifndef SQUID_SRC_COMMCALLS_H
10 #define SQUID_SRC_COMMCALLS_H
11
12 #include "base/AsyncCall.h"
13 #include "base/AsyncJobCalls.h"
14 #include "comm/Flag.h"
15 #include "comm/forward.h"
16 #include "MasterXaction.h"
17
18 /* CommCalls implement AsyncCall interface for comm_* callbacks.
19 * The classes cover two call dialer kinds:
20 * - A C-style call using a function pointer (deprecated);
21 * - A C++-style call to an AsyncJob child.
22 * and several comm_* callback kinds:
23 * - accept (IOACB)
24 * - connect (CNCB)
25 * - I/O (IOCB)
26 * - timeout (CTCB)
27 * - close (CLCB)
28 */
29
30 class CommAcceptCbParams;
31 typedef void IOACB(const CommAcceptCbParams &params);
32
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);
35
36 class CommTimeoutCbParams;
37 typedef void CTCB(const CommTimeoutCbParams &params);
38
39 class CommCloseCbParams;
40 typedef void CLCB(const CommCloseCbParams &params);
41
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 */
51
52 /* Comm*CbParams classes below handle callback parameters */
53
54 // Maintains parameters common to all comm callbacks
55 class CommCommonCbParams
56 {
57 public:
58 CommCommonCbParams(void *aData);
59 CommCommonCbParams(const CommCommonCbParams &params);
60 ~CommCommonCbParams();
61
62 /// adjust using the current Comm state; returns false to cancel the call
63 // not virtual because callers know dialer type
64 bool syncWithComm() { return true; }
65
66 void print(std::ostream &os) const;
67
68 public:
69 void *data; // cbdata-protected
70
71 /** The connection which this call pertains to.
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.
78 * + NP: timeouts might also return to the connect/read/write handler with Comm::TIMEOUT.
79 */
80 Comm::ConnectionPointer conn;
81
82 Comm::Flag flag; ///< comm layer result status.
83 int xerrno; ///< The last errno to occur. non-zero if flag is Comm::COMM_ERROR.
84
85 int fd; ///< FD which the call was about. Set by the async call creator.
86 private:
87 // should not be needed and not yet implemented
88 CommCommonCbParams &operator =(const CommCommonCbParams &params);
89 };
90
91 // accept parameters
92 class CommAcceptCbParams: public CommCommonCbParams
93 {
94 public:
95 CommAcceptCbParams(void *aData);
96
97 void print(std::ostream &os) const;
98
99 /// the configuration listening port this call relates to (may be nil)
100 AnyP::PortCfgPointer port;
101 };
102
103 // connect parameters
104 class CommConnectCbParams: public CommCommonCbParams
105 {
106 public:
107 CommConnectCbParams(void *aData);
108
109 bool syncWithComm(); // see CommCommonCbParams::syncWithComm
110 };
111
112 // read/write (I/O) parameters
113 class CommIoCbParams: public CommCommonCbParams
114 {
115 public:
116 CommIoCbParams(void *aData);
117
118 void print(std::ostream &os) const;
119 bool syncWithComm(); // see CommCommonCbParams::syncWithComm
120
121 public:
122 char *buf;
123 size_t size;
124 };
125
126 // close parameters
127 class CommCloseCbParams: public CommCommonCbParams
128 {
129 public:
130 CommCloseCbParams(void *aData);
131 };
132
133 class CommTimeoutCbParams: public CommCommonCbParams
134 {
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_>
142 class CommDialerParamsT
143 {
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>
154 Params &GetCommParams(AsyncCall::Pointer &call)
155 {
156 typedef CommDialerParamsT<Params> DialerParams;
157 DialerParams *dp = dynamic_cast<DialerParams*>(call->getDialer());
158 assert(dp);
159 return dp->params;
160 }
161
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_>
165 class CommCbMemFunT: public JobDialer<C>, public CommDialerParamsT<Params_>
166 {
167 public:
168 typedef Params_ Params;
169 typedef void (C::*Method)(const Params &io);
170
171 CommCbMemFunT(const CbcPointer<C> &aJob, Method aMeth): JobDialer<C>(aJob),
172 CommDialerParamsT<Params_>(aJob->toCbdata()),
173 method(aMeth) {}
174
175 bool canDial(AsyncCall &c) override {
176 return JobDialer<C>::canDial(c) &&
177 this->params.syncWithComm();
178 }
179
180 void print(std::ostream &os) const override {
181 os << '(';
182 this->params.print(os);
183 os << ')';
184 }
185
186 public:
187 Method method;
188
189 protected:
190 void doDial() override { ((&(*this->job))->*method)(this->params); }
191 };
192
193 // accept (IOACB) dialer
194 class CommAcceptCbPtrFun: public CallDialer,
195 public CommDialerParamsT<CommAcceptCbParams>
196 {
197 public:
198 typedef CommAcceptCbParams Params;
199 typedef RefCount<CommAcceptCbPtrFun> Pointer;
200
201 CommAcceptCbPtrFun(IOACB *aHandler, const CommAcceptCbParams &aParams);
202 CommAcceptCbPtrFun(const CommAcceptCbPtrFun &o);
203
204 void dial();
205
206 void print(std::ostream &os) const override;
207
208 public:
209 IOACB *handler;
210 };
211
212 // connect (CNCB) dialer
213 class CommConnectCbPtrFun: public CallDialer,
214 public CommDialerParamsT<CommConnectCbParams>
215 {
216 public:
217 typedef CommConnectCbParams Params;
218
219 CommConnectCbPtrFun(CNCB *aHandler, const Params &aParams);
220 void dial();
221
222 void print(std::ostream &os) const override;
223
224 public:
225 CNCB *handler;
226 };
227
228 // read/write (IOCB) dialer
229 class CommIoCbPtrFun: public CallDialer,
230 public CommDialerParamsT<CommIoCbParams>
231 {
232 public:
233 typedef CommIoCbParams Params;
234
235 CommIoCbPtrFun(IOCB *aHandler, const Params &aParams);
236 void dial();
237
238 void print(std::ostream &os) const override;
239
240 public:
241 IOCB *handler;
242 };
243
244 // close (CLCB) dialer
245 class CommCloseCbPtrFun: public CallDialer,
246 public CommDialerParamsT<CommCloseCbParams>
247 {
248 public:
249 typedef CommCloseCbParams Params;
250
251 CommCloseCbPtrFun(CLCB *aHandler, const Params &aParams);
252 void dial();
253
254 void print(std::ostream &os) const override;
255
256 public:
257 CLCB *handler;
258 };
259
260 class CommTimeoutCbPtrFun:public CallDialer,
261 public CommDialerParamsT<CommTimeoutCbParams>
262 {
263 public:
264 typedef CommTimeoutCbParams Params;
265
266 CommTimeoutCbPtrFun(CTCB *aHandler, const Params &aParams);
267 void dial();
268
269 void print(std::ostream &os) const override;
270
271 public:
272 CTCB *handler;
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>
280 class CommCbFunPtrCallT: public AsyncCall
281 {
282 public:
283 typedef RefCount<CommCbFunPtrCallT<Dialer> > Pointer;
284 typedef typename Dialer::Params Params;
285
286 inline CommCbFunPtrCallT(int debugSection, int debugLevel,
287 const char *callName, const Dialer &aDialer);
288
289 inline CommCbFunPtrCallT(const CommCbFunPtrCallT &o) :
290 AsyncCall(o.debugSection, o.debugLevel, o.name),
291 dialer(o.dialer) {}
292
293 ~CommCbFunPtrCallT() override {}
294
295 CallDialer* getDialer() override { return &dialer; }
296
297 public:
298 Dialer dialer;
299
300 protected:
301 inline bool canFire() override;
302 inline void fire() override;
303
304 private:
305 CommCbFunPtrCallT & operator=(const CommCbFunPtrCallT &); // not defined. not permitted.
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,
313 const char *callName, const Dialer &dialer)
314 {
315 return new CommCbFunPtrCallT<Dialer>(debugSection, debugLevel, callName,
316 dialer);
317 }
318
319 /* inlined implementation of templated methods */
320
321 /* CommCbFunPtrCallT */
322
323 template <class Dialer>
324 CommCbFunPtrCallT<Dialer>::CommCbFunPtrCallT(int aDebugSection, int aDebugLevel,
325 const char *callName, const Dialer &aDialer):
326 AsyncCall(aDebugSection, aDebugLevel, callName),
327 dialer(aDialer)
328 {
329 }
330
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
341 if (!dialer.params.syncWithComm())
342 return cancel("out of sync w/comm");
343
344 if (!dialer.handler)
345 return cancel("no callback requested");
346
347 return true;
348 }
349
350 template <class Dialer>
351 void
352 CommCbFunPtrCallT<Dialer>::fire()
353 {
354 dialer.dial();
355 }
356
357 #endif /* SQUID_SRC_COMMCALLS_H */
358