2 * Copyright (C) 1996-2019 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_COMMCALLS_H
10 #define SQUID_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:
28 * and a special callback kind for passing pipe FD, disk FD or fd_table index 'FD' to the handler:
29 * - FD passing callback (FDECB)
32 class CommAcceptCbParams
;
33 typedef void IOACB(const CommAcceptCbParams
¶ms
);
35 typedef void CNCB(const Comm::ConnectionPointer
&conn
, Comm::Flag status
, int xerrno
, void *data
);
36 typedef void IOCB(const Comm::ConnectionPointer
&conn
, char *, size_t size
, Comm::Flag flag
, int xerrno
, void *data
);
38 class CommTimeoutCbParams
;
39 typedef void CTCB(const CommTimeoutCbParams
¶ms
);
41 class CommCloseCbParams
;
42 typedef void CLCB(const CommCloseCbParams
¶ms
);
45 typedef void FDECB(const FdeCbParams
¶ms
);
48 * TODO: When there are no function-pointer-based callbacks left, all
49 * this complexity can be removed. Jobs that need comm services will just
50 * implement CommReader, CommWriter, etc. interfaces and receive calls
51 * using general (not comm-specific) AsyncCall code. For now, we have to
52 * allow the caller to create a callback that comm can modify to set
53 * parameters, which is not trivial when the caller type/kind is not
54 * known to comm and there are many kinds of parameters.
57 /* Comm*CbParams classes below handle callback parameters */
59 // Maintains parameters common to all comm callbacks
60 class CommCommonCbParams
63 CommCommonCbParams(void *aData
);
64 CommCommonCbParams(const CommCommonCbParams
¶ms
);
65 ~CommCommonCbParams();
67 /// adjust using the current Comm state; returns false to cancel the call
68 // not virtual because callers know dialer type
69 bool syncWithComm() { return true; }
71 void print(std::ostream
&os
) const;
74 void *data
; // cbdata-protected
76 /** The connection which this call pertains to.
77 * - On accept() calls this is the new client connection.
78 * - On connect() finished calls this is the newely opened connection.
79 * - On write calls this is the connection just written to.
80 * - On read calls this is the connection just read from.
81 * - On close calls this describes the connection which is now closed.
82 * - On timeouts this is the connection whose operation timed out.
83 * + NP: timeouts might also return to the connect/read/write handler with Comm::TIMEOUT.
85 Comm::ConnectionPointer conn
;
87 Comm::Flag flag
; ///< comm layer result status.
88 int xerrno
; ///< The last errno to occur. non-zero if flag is Comm::COMM_ERROR.
90 int fd
; ///< FD which the call was about. Set by the async call creator.
92 // should not be needed and not yet implemented
93 CommCommonCbParams
&operator =(const CommCommonCbParams
¶ms
);
97 class CommAcceptCbParams
: public CommCommonCbParams
100 CommAcceptCbParams(void *aData
);
102 void print(std::ostream
&os
) const;
104 /// Transaction which this call is part of.
105 MasterXaction::Pointer xaction
;
108 // connect parameters
109 class CommConnectCbParams
: public CommCommonCbParams
112 CommConnectCbParams(void *aData
);
114 bool syncWithComm(); // see CommCommonCbParams::syncWithComm
117 // read/write (I/O) parameters
118 class CommIoCbParams
: public CommCommonCbParams
121 CommIoCbParams(void *aData
);
123 void print(std::ostream
&os
) const;
124 bool syncWithComm(); // see CommCommonCbParams::syncWithComm
132 class CommCloseCbParams
: public CommCommonCbParams
135 CommCloseCbParams(void *aData
);
138 class CommTimeoutCbParams
: public CommCommonCbParams
141 CommTimeoutCbParams(void *aData
);
144 /// Special Calls parameter, for direct use of an FD without a controlling Comm::Connection
145 /// This is used for pipe() FD with helpers, and internally by Comm when handling some special FD actions.
146 class FdeCbParams
: public CommCommonCbParams
149 FdeCbParams(void *aData
);
150 // TODO make this a standalone object with FD value and pointer to fde table entry.
151 // that requires all the existing Comm handlers to be updated first though
154 // Interface to expose comm callback parameters of all comm dialers.
155 // GetCommParams() uses this interface to access comm parameters.
156 template <class Params_
>
157 class CommDialerParamsT
160 typedef Params_ Params
;
161 CommDialerParamsT(const Params
&io
): params(io
) {}
167 // Get comm params of an async comm call
168 template <class Params
>
169 Params
&GetCommParams(AsyncCall::Pointer
&call
)
171 typedef CommDialerParamsT
<Params
> DialerParams
;
172 DialerParams
*dp
= dynamic_cast<DialerParams
*>(call
->getDialer());
177 // All job dialers with comm parameters are merged into one since they
178 // all have exactly one callback argument and differ in Params type only
179 template <class C
, class Params_
>
180 class CommCbMemFunT
: public JobDialer
<C
>, public CommDialerParamsT
<Params_
>
183 typedef Params_ Params
;
184 typedef void (C::*Method
)(const Params
&io
);
186 CommCbMemFunT(const CbcPointer
<C
> &aJob
, Method aMeth
): JobDialer
<C
>(aJob
),
187 CommDialerParamsT
<Params_
>(aJob
->toCbdata()),
190 virtual bool canDial(AsyncCall
&c
) {
191 return JobDialer
<C
>::canDial(c
) &&
192 this->params
.syncWithComm();
195 virtual void print(std::ostream
&os
) const {
197 this->params
.print(os
);
205 virtual void doDial() { ((&(*this->job
))->*method
)(this->params
); }
208 // accept (IOACB) dialer
209 class CommAcceptCbPtrFun
: public CallDialer
,
210 public CommDialerParamsT
<CommAcceptCbParams
>
213 typedef CommAcceptCbParams Params
;
214 typedef RefCount
<CommAcceptCbPtrFun
> Pointer
;
216 CommAcceptCbPtrFun(IOACB
*aHandler
, const CommAcceptCbParams
&aParams
);
217 CommAcceptCbPtrFun(const CommAcceptCbPtrFun
&o
);
221 virtual void print(std::ostream
&os
) const;
227 // connect (CNCB) dialer
228 class CommConnectCbPtrFun
: public CallDialer
,
229 public CommDialerParamsT
<CommConnectCbParams
>
232 typedef CommConnectCbParams Params
;
234 CommConnectCbPtrFun(CNCB
*aHandler
, const Params
&aParams
);
237 virtual void print(std::ostream
&os
) const;
243 // read/write (IOCB) dialer
244 class CommIoCbPtrFun
: public CallDialer
,
245 public CommDialerParamsT
<CommIoCbParams
>
248 typedef CommIoCbParams Params
;
250 CommIoCbPtrFun(IOCB
*aHandler
, const Params
&aParams
);
253 virtual void print(std::ostream
&os
) const;
259 // close (CLCB) dialer
260 class CommCloseCbPtrFun
: public CallDialer
,
261 public CommDialerParamsT
<CommCloseCbParams
>
264 typedef CommCloseCbParams Params
;
266 CommCloseCbPtrFun(CLCB
*aHandler
, const Params
&aParams
);
269 virtual void print(std::ostream
&os
) const;
275 class CommTimeoutCbPtrFun
:public CallDialer
,
276 public CommDialerParamsT
<CommTimeoutCbParams
>
279 typedef CommTimeoutCbParams Params
;
281 CommTimeoutCbPtrFun(CTCB
*aHandler
, const Params
&aParams
);
284 virtual void print(std::ostream
&os
) const;
290 /// FD event (FDECB) dialer
291 class FdeCbPtrFun
: public CallDialer
,
292 public CommDialerParamsT
<FdeCbParams
>
295 typedef FdeCbParams Params
;
297 FdeCbPtrFun(FDECB
*aHandler
, const Params
&aParams
);
299 virtual void print(std::ostream
&os
) const;
305 // AsyncCall to comm handlers implemented as global functions.
306 // The dialer is one of the Comm*CbPtrFunT above
307 // TODO: Get rid of this class by moving canFire() to canDial() method
309 template <class Dialer
>
310 class CommCbFunPtrCallT
: public AsyncCall
313 typedef RefCount
<CommCbFunPtrCallT
<Dialer
> > Pointer
;
314 typedef typename
Dialer::Params Params
;
316 inline CommCbFunPtrCallT(int debugSection
, int debugLevel
,
317 const char *callName
, const Dialer
&aDialer
);
319 inline CommCbFunPtrCallT(const CommCbFunPtrCallT
&o
) :
320 AsyncCall(o
.debugSection
, o
.debugLevel
, o
.name
),
323 ~CommCbFunPtrCallT() {}
325 virtual CallDialer
* getDialer() { return &dialer
; }
331 inline virtual bool canFire();
332 inline virtual void fire();
335 CommCbFunPtrCallT
& operator=(const CommCbFunPtrCallT
&); // not defined. not permitted.
338 // Conveninece wrapper: It is often easier to call a templated function than
339 // to create a templated class.
340 template <class Dialer
>
342 CommCbFunPtrCallT
<Dialer
> *commCbCall(int debugSection
, int debugLevel
,
343 const char *callName
, const Dialer
&dialer
)
345 return new CommCbFunPtrCallT
<Dialer
>(debugSection
, debugLevel
, callName
,
349 /* inlined implementation of templated methods */
351 /* CommCbFunPtrCallT */
353 template <class Dialer
>
354 CommCbFunPtrCallT
<Dialer
>::CommCbFunPtrCallT(int aDebugSection
, int aDebugLevel
,
355 const char *callName
, const Dialer
&aDialer
):
356 AsyncCall(aDebugSection
, aDebugLevel
, callName
),
361 template <class Dialer
>
363 CommCbFunPtrCallT
<Dialer
>::canFire()
365 if (!AsyncCall::canFire())
368 if (!cbdataReferenceValid(dialer
.params
.data
))
369 return cancel("callee gone");
371 if (!dialer
.params
.syncWithComm())
372 return cancel("out of sync w/comm");
375 return cancel("no callback requested");
380 template <class Dialer
>
382 CommCbFunPtrCallT
<Dialer
>::fire()
387 #endif /* SQUID_COMMCALLS_H */