2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
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.
9 #ifndef SQUID_SRC_COMMCALLS_H
10 #define SQUID_SRC_COMMCALLS_H
12 #include "base/AsyncCall.h"
13 #include "base/AsyncJobCalls.h"
14 #include "comm/Flag.h"
15 #include "comm/forward.h"
16 #include "MasterXaction.h"
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:
30 class CommAcceptCbParams
;
31 typedef void IOACB(const CommAcceptCbParams
¶ms
);
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
);
36 class CommTimeoutCbParams
;
37 typedef void CTCB(const CommTimeoutCbParams
¶ms
);
39 class CommCloseCbParams
;
40 typedef void CLCB(const CommCloseCbParams
¶ms
);
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.
52 /* Comm*CbParams classes below handle callback parameters */
54 // Maintains parameters common to all comm callbacks
55 class CommCommonCbParams
58 CommCommonCbParams(void *aData
);
59 CommCommonCbParams(const CommCommonCbParams
¶ms
);
60 ~CommCommonCbParams();
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; }
66 void print(std::ostream
&os
) const;
69 void *data
; // cbdata-protected
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.
80 Comm::ConnectionPointer conn
;
82 Comm::Flag flag
; ///< comm layer result status.
83 int xerrno
; ///< The last errno to occur. non-zero if flag is Comm::COMM_ERROR.
85 int fd
; ///< FD which the call was about. Set by the async call creator.
87 // should not be needed and not yet implemented
88 CommCommonCbParams
&operator =(const CommCommonCbParams
¶ms
);
92 class CommAcceptCbParams
: public CommCommonCbParams
95 CommAcceptCbParams(void *aData
);
97 void print(std::ostream
&os
) const;
99 /// the configuration listening port this call relates to (may be nil)
100 AnyP::PortCfgPointer port
;
103 // connect parameters
104 class CommConnectCbParams
: public CommCommonCbParams
107 CommConnectCbParams(void *aData
);
109 bool syncWithComm(); // see CommCommonCbParams::syncWithComm
112 // read/write (I/O) parameters
113 class CommIoCbParams
: public CommCommonCbParams
116 CommIoCbParams(void *aData
);
118 void print(std::ostream
&os
) const;
119 bool syncWithComm(); // see CommCommonCbParams::syncWithComm
127 class CommCloseCbParams
: public CommCommonCbParams
130 CommCloseCbParams(void *aData
);
133 class CommTimeoutCbParams
: public CommCommonCbParams
136 CommTimeoutCbParams(void *aData
);
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
145 typedef Params_ Params
;
146 CommDialerParamsT(const Params
&io
): params(io
) {}
152 // Get comm params of an async comm call
153 template <class Params
>
154 Params
&GetCommParams(AsyncCall::Pointer
&call
)
156 typedef CommDialerParamsT
<Params
> DialerParams
;
157 DialerParams
*dp
= dynamic_cast<DialerParams
*>(call
->getDialer());
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_
>
168 typedef Params_ Params
;
169 typedef void (C::*Method
)(const Params
&io
);
171 CommCbMemFunT(const CbcPointer
<C
> &aJob
, Method aMeth
): JobDialer
<C
>(aJob
),
172 CommDialerParamsT
<Params_
>(aJob
->toCbdata()),
175 bool canDial(AsyncCall
&c
) override
{
176 return JobDialer
<C
>::canDial(c
) &&
177 this->params
.syncWithComm();
180 void print(std::ostream
&os
) const override
{
182 this->params
.print(os
);
190 void doDial() override
{ ((&(*this->job
))->*method
)(this->params
); }
193 // accept (IOACB) dialer
194 class CommAcceptCbPtrFun
: public CallDialer
,
195 public CommDialerParamsT
<CommAcceptCbParams
>
198 typedef CommAcceptCbParams Params
;
199 typedef RefCount
<CommAcceptCbPtrFun
> Pointer
;
201 CommAcceptCbPtrFun(IOACB
*aHandler
, const CommAcceptCbParams
&aParams
);
202 CommAcceptCbPtrFun(const CommAcceptCbPtrFun
&o
);
206 void print(std::ostream
&os
) const override
;
212 // connect (CNCB) dialer
213 class CommConnectCbPtrFun
: public CallDialer
,
214 public CommDialerParamsT
<CommConnectCbParams
>
217 typedef CommConnectCbParams Params
;
219 CommConnectCbPtrFun(CNCB
*aHandler
, const Params
&aParams
);
222 void print(std::ostream
&os
) const override
;
228 // read/write (IOCB) dialer
229 class CommIoCbPtrFun
: public CallDialer
,
230 public CommDialerParamsT
<CommIoCbParams
>
233 typedef CommIoCbParams Params
;
235 CommIoCbPtrFun(IOCB
*aHandler
, const Params
&aParams
);
238 void print(std::ostream
&os
) const override
;
244 // close (CLCB) dialer
245 class CommCloseCbPtrFun
: public CallDialer
,
246 public CommDialerParamsT
<CommCloseCbParams
>
249 typedef CommCloseCbParams Params
;
251 CommCloseCbPtrFun(CLCB
*aHandler
, const Params
&aParams
);
254 void print(std::ostream
&os
) const override
;
260 class CommTimeoutCbPtrFun
:public CallDialer
,
261 public CommDialerParamsT
<CommTimeoutCbParams
>
264 typedef CommTimeoutCbParams Params
;
266 CommTimeoutCbPtrFun(CTCB
*aHandler
, const Params
&aParams
);
269 void print(std::ostream
&os
) const override
;
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
279 template <class Dialer
>
280 class CommCbFunPtrCallT
: public AsyncCall
283 typedef RefCount
<CommCbFunPtrCallT
<Dialer
> > Pointer
;
284 typedef typename
Dialer::Params Params
;
286 inline CommCbFunPtrCallT(int debugSection
, int debugLevel
,
287 const char *callName
, const Dialer
&aDialer
);
289 inline CommCbFunPtrCallT(const CommCbFunPtrCallT
&o
) :
290 AsyncCall(o
.debugSection
, o
.debugLevel
, o
.name
),
293 ~CommCbFunPtrCallT() override
{}
295 CallDialer
* getDialer() override
{ return &dialer
; }
301 inline bool canFire() override
;
302 inline void fire() override
;
305 CommCbFunPtrCallT
& operator=(const CommCbFunPtrCallT
&); // not defined. not permitted.
308 // Conveninece wrapper: It is often easier to call a templated function than
309 // to create a templated class.
310 template <class Dialer
>
312 CommCbFunPtrCallT
<Dialer
> *commCbCall(int debugSection
, int debugLevel
,
313 const char *callName
, const Dialer
&dialer
)
315 return new CommCbFunPtrCallT
<Dialer
>(debugSection
, debugLevel
, callName
,
319 /* inlined implementation of templated methods */
321 /* CommCbFunPtrCallT */
323 template <class Dialer
>
324 CommCbFunPtrCallT
<Dialer
>::CommCbFunPtrCallT(int aDebugSection
, int aDebugLevel
,
325 const char *callName
, const Dialer
&aDialer
):
326 AsyncCall(aDebugSection
, aDebugLevel
, callName
),
331 template <class Dialer
>
333 CommCbFunPtrCallT
<Dialer
>::canFire()
335 if (!AsyncCall::canFire())
338 if (!cbdataReferenceValid(dialer
.params
.data
))
339 return cancel("callee gone");
341 if (!dialer
.params
.syncWithComm())
342 return cancel("out of sync w/comm");
345 return cancel("no callback requested");
350 template <class Dialer
>
352 CommCbFunPtrCallT
<Dialer
>::fire()
357 #endif /* SQUID_SRC_COMMCALLS_H */