]> git.ipfire.org Git - thirdparty/squid.git/blame - src/CommCalls.h
SourceFormat Enforcement
[thirdparty/squid.git] / src / CommCalls.h
CommitLineData
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
24class CommAcceptCbParams;
25typedef void IOACB(const CommAcceptCbParams &params);
26
f01d4b80 27typedef void CNCB(const Comm::ConnectionPointer &conn, comm_err_t status, int xerrno, void *data);
a138c8fc 28typedef void IOCB(const Comm::ConnectionPointer &conn, char *, size_t size, comm_err_t flag, int xerrno, void *data);
f9b72e0c 29
8d77a37c
AJ
30class CommTimeoutCbParams;
31typedef void CTCB(const CommTimeoutCbParams &params);
32
575d05c4
AJ
33class CommCloseCbParams;
34typedef void CLCB(const CommCloseCbParams &params);
35
a17bf806
AJ
36class FdeCbParams;
37typedef void FDECB(const FdeCbParams &params);
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
52class CommCommonCbParams
53{
b0469965 54public:
55 CommCommonCbParams(void *aData);
56 CommCommonCbParams(const CommCommonCbParams &params);
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
65public:
66 void *data; // cbdata-protected
3e4bebf8
AJ
67
68 /** The connection which this call pertains to.
69 * \itemize On accept() calls this is the new client connection.
70 * \itemize On connect() finished calls this is the newely opened connection.
71 * \itemize On write calls this is the connection just written to.
72 * \itemize On read calls this is the connection just read from.
73 * \itemize On close calls this describes the connection which is now closed.
74 * \itemize On timeouts this is the connection whose operation timed out.
8d77a37c 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 83private:
84 // should not be needed and not yet implemented
26ac0430 85 CommCommonCbParams &operator =(const CommCommonCbParams &params);
b0469965 86};
87
88// accept parameters
26ac0430
AJ
89class CommAcceptCbParams: public CommCommonCbParams
90{
b0469965 91public:
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
101class CommConnectCbParams: public CommCommonCbParams
102{
b0469965 103public:
104 CommConnectCbParams(void *aData);
4c3ba68d
AR
105
106 bool syncWithComm(); // see CommCommonCbParams::syncWithComm
b0469965 107};
108
109// read/write (I/O) parameters
26ac0430
AJ
110class CommIoCbParams: public CommCommonCbParams
111{
b0469965 112public:
113 CommIoCbParams(void *aData);
114
115 void print(std::ostream &os) const;
4c3ba68d 116 bool syncWithComm(); // see CommCommonCbParams::syncWithComm
b0469965 117
118public:
119 char *buf;
120 size_t size;
121};
122
123// close parameters
26ac0430
AJ
124class CommCloseCbParams: public CommCommonCbParams
125{
b0469965 126public:
127 CommCloseCbParams(void *aData);
128};
129
26ac0430
AJ
130class CommTimeoutCbParams: public CommCommonCbParams
131{
b0469965 132public:
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.
138class FdeCbParams: public CommCommonCbParams
139{
140public:
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.
148template <class Params_>
26ac0430
AJ
149class CommDialerParamsT
150{
b0469965 151public:
152 typedef Params_ Params;
153 CommDialerParamsT(const Params &io): params(io) {}
154
155public:
156 Params params;
157};
158
159// Get comm params of an async comm call
160template <class Params>
26ac0430
AJ
161Params &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
171template <class C, class Params_>
4299f876 172class CommCbMemFunT: public JobDialer<C>, public CommDialerParamsT<Params_>
b0469965 173{
174public:
175 typedef Params_ Params;
176 typedef void (C::*Method)(const Params &io);
177
5f621cd0
AJ
178 CommCbMemFunT(const CbcPointer<C> &aJob, Method aMeth): JobDialer<C>(aJob),
179 CommDialerParamsT<Params_>(aJob.get()),
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
193public:
b0469965 194 Method method;
195
196protected:
4299f876 197 virtual void doDial() { ((&(*this->job))->*method)(this->params); }
b0469965 198};
199
b0469965 200// accept (IOACB) dialer
201class CommAcceptCbPtrFun: public CallDialer,
e1381638 202 public CommDialerParamsT<CommAcceptCbParams>
b0469965 203{
204public:
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
215public:
216 IOACB *handler;
217};
218
219// connect (CNCB) dialer
220class CommConnectCbPtrFun: public CallDialer,
e1381638 221 public CommDialerParamsT<CommConnectCbParams>
b0469965 222{
223public:
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
231public:
232 CNCB *handler;
233};
234
b0469965 235// read/write (IOCB) dialer
236class CommIoCbPtrFun: public CallDialer,
e1381638 237 public CommDialerParamsT<CommIoCbParams>
b0469965 238{
239public:
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
247public:
248 IOCB *handler;
249};
250
575d05c4 251// close (CLCB) dialer
b0469965 252class CommCloseCbPtrFun: public CallDialer,
e1381638 253 public CommDialerParamsT<CommCloseCbParams>
b0469965 254{
255public:
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
263public:
575d05c4 264 CLCB *handler;
b0469965 265};
266
267class CommTimeoutCbPtrFun:public CallDialer,
e1381638 268 public CommDialerParamsT<CommTimeoutCbParams>
b0469965 269{
270public:
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
278public:
8d77a37c 279 CTCB *handler;
b0469965 280};
281
a17bf806
AJ
282/// FD event (FDECB) dialer
283class FdeCbPtrFun: public CallDialer,
284 public CommDialerParamsT<FdeCbParams>
285{
286public:
287 typedef FdeCbParams Params;
288
289 FdeCbPtrFun(FDECB *aHandler, const Params &aParams);
290 void dial();
291 virtual void print(std::ostream &os) const;
292
293public:
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.
301template <class Dialer>
26ac0430
AJ
302class CommCbFunPtrCallT: public AsyncCall
303{
b0469965 304public:
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
319public:
320 Dialer dialer;
321
322protected:
323 inline virtual bool canFire();
324 inline virtual void fire();
cbff89ba
AJ
325
326private:
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.
332template <class Dialer>
333inline
334CommCbFunPtrCallT<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
345template <class Dialer>
18ec8500 346CommCbFunPtrCallT<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 353template <class Dialer>
354bool
355CommCbFunPtrCallT<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
372template <class Dialer>
373void
374CommCbFunPtrCallT<Dialer>::fire()
375{
376 dialer.dial();
377}
378
379#endif /* SQUID_COMMCALLS_H */