1 #ifndef SQUID_COMMCALLS_H
2 #define SQUID_COMMCALLS_H
4 #include "base/AsyncCall.h"
5 #include "base/AsyncJobCalls.h"
7 #include "comm/forward.h"
8 #include "MasterXaction.h"
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.
14 * and several comm_* callback kinds:
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)
24 class CommAcceptCbParams
;
25 typedef void IOACB(const CommAcceptCbParams
¶ms
);
27 typedef void CNCB(const Comm::ConnectionPointer
&conn
, Comm::Flag status
, int xerrno
, void *data
);
28 typedef void IOCB(const Comm::ConnectionPointer
&conn
, char *, size_t size
, Comm::Flag flag
, int xerrno
, void *data
);
30 class CommTimeoutCbParams
;
31 typedef void CTCB(const CommTimeoutCbParams
¶ms
);
33 class CommCloseCbParams
;
34 typedef void CLCB(const CommCloseCbParams
¶ms
);
37 typedef void FDECB(const FdeCbParams
¶ms
);
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.
49 /* Comm*CbParams classes below handle callback parameters */
51 // Maintains parameters common to all comm callbacks
52 class CommCommonCbParams
55 CommCommonCbParams(void *aData
);
56 CommCommonCbParams(const CommCommonCbParams
¶ms
);
57 ~CommCommonCbParams();
59 /// adjust using the current Comm state; returns false to cancel the call
60 // not virtual because callers know dialer type
61 bool syncWithComm() { return true; }
63 void print(std::ostream
&os
) const;
66 void *data
; // cbdata-protected
68 /** The connection which this call pertains to.
69 * - On accept() calls this is the new client connection.
70 * - On connect() finished calls this is the newely opened connection.
71 * - On write calls this is the connection just written to.
72 * - On read calls this is the connection just read from.
73 * - On close calls this describes the connection which is now closed.
74 * - On timeouts this is the connection whose operation timed out.
75 * + NP: timeouts might also return to the connect/read/write handler with Comm::TIMEOUT.
77 Comm::ConnectionPointer conn
;
79 Comm::Flag flag
; ///< comm layer result status.
80 int xerrno
; ///< The last errno to occur. non-zero if flag is Comm::ERROR.
82 int fd
; ///< FD which the call was about. Set by the async call creator.
84 // should not be needed and not yet implemented
85 CommCommonCbParams
&operator =(const CommCommonCbParams
¶ms
);
89 class CommAcceptCbParams
: public CommCommonCbParams
92 CommAcceptCbParams(void *aData
);
94 void print(std::ostream
&os
) const;
96 /// Transaction which this call is part of.
97 MasterXaction::Pointer xaction
;
100 // connect parameters
101 class CommConnectCbParams
: public CommCommonCbParams
104 CommConnectCbParams(void *aData
);
106 bool syncWithComm(); // see CommCommonCbParams::syncWithComm
109 // read/write (I/O) parameters
110 class CommIoCbParams
: public CommCommonCbParams
113 CommIoCbParams(void *aData
);
115 void print(std::ostream
&os
) const;
116 bool syncWithComm(); // see CommCommonCbParams::syncWithComm
124 class CommCloseCbParams
: public CommCommonCbParams
127 CommCloseCbParams(void *aData
);
130 class CommTimeoutCbParams
: public CommCommonCbParams
133 CommTimeoutCbParams(void *aData
);
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.
138 class FdeCbParams
: public CommCommonCbParams
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
146 // Interface to expose comm callback parameters of all comm dialers.
147 // GetCommParams() uses this interface to access comm parameters.
148 template <class Params_
>
149 class CommDialerParamsT
152 typedef Params_ Params
;
153 CommDialerParamsT(const Params
&io
): params(io
) {}
159 // Get comm params of an async comm call
160 template <class Params
>
161 Params
&GetCommParams(AsyncCall::Pointer
&call
)
163 typedef CommDialerParamsT
<Params
> DialerParams
;
164 DialerParams
*dp
= dynamic_cast<DialerParams
*>(call
->getDialer());
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
171 template <class C
, class Params_
>
172 class CommCbMemFunT
: public JobDialer
<C
>, public CommDialerParamsT
<Params_
>
175 typedef Params_ Params
;
176 typedef void (C::*Method
)(const Params
&io
);
178 CommCbMemFunT(const CbcPointer
<C
> &aJob
, Method aMeth
): JobDialer
<C
>(aJob
),
179 CommDialerParamsT
<Params_
>(aJob
->toCbdata()),
182 virtual bool canDial(AsyncCall
&c
) {
183 return JobDialer
<C
>::canDial(c
) &&
184 this->params
.syncWithComm();
187 virtual void print(std::ostream
&os
) const {
189 this->params
.print(os
);
197 virtual void doDial() { ((&(*this->job
))->*method
)(this->params
); }
200 // accept (IOACB) dialer
201 class CommAcceptCbPtrFun
: public CallDialer
,
202 public CommDialerParamsT
<CommAcceptCbParams
>
205 typedef CommAcceptCbParams Params
;
206 typedef RefCount
<CommAcceptCbPtrFun
> Pointer
;
208 CommAcceptCbPtrFun(IOACB
*aHandler
, const CommAcceptCbParams
&aParams
);
209 CommAcceptCbPtrFun(const CommAcceptCbPtrFun
&o
);
213 virtual void print(std::ostream
&os
) const;
219 // connect (CNCB) dialer
220 class CommConnectCbPtrFun
: public CallDialer
,
221 public CommDialerParamsT
<CommConnectCbParams
>
224 typedef CommConnectCbParams Params
;
226 CommConnectCbPtrFun(CNCB
*aHandler
, const Params
&aParams
);
229 virtual void print(std::ostream
&os
) const;
235 // read/write (IOCB) dialer
236 class CommIoCbPtrFun
: public CallDialer
,
237 public CommDialerParamsT
<CommIoCbParams
>
240 typedef CommIoCbParams Params
;
242 CommIoCbPtrFun(IOCB
*aHandler
, const Params
&aParams
);
245 virtual void print(std::ostream
&os
) const;
251 // close (CLCB) dialer
252 class CommCloseCbPtrFun
: public CallDialer
,
253 public CommDialerParamsT
<CommCloseCbParams
>
256 typedef CommCloseCbParams Params
;
258 CommCloseCbPtrFun(CLCB
*aHandler
, const Params
&aParams
);
261 virtual void print(std::ostream
&os
) const;
267 class CommTimeoutCbPtrFun
:public CallDialer
,
268 public CommDialerParamsT
<CommTimeoutCbParams
>
271 typedef CommTimeoutCbParams Params
;
273 CommTimeoutCbPtrFun(CTCB
*aHandler
, const Params
&aParams
);
276 virtual void print(std::ostream
&os
) const;
282 /// FD event (FDECB) dialer
283 class FdeCbPtrFun
: public CallDialer
,
284 public CommDialerParamsT
<FdeCbParams
>
287 typedef FdeCbParams Params
;
289 FdeCbPtrFun(FDECB
*aHandler
, const Params
&aParams
);
291 virtual void print(std::ostream
&os
) const;
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
301 template <class Dialer
>
302 class CommCbFunPtrCallT
: public AsyncCall
305 typedef RefCount
<CommCbFunPtrCallT
<Dialer
> > Pointer
;
306 typedef typename
Dialer::Params Params
;
308 inline CommCbFunPtrCallT(int debugSection
, int debugLevel
,
309 const char *callName
, const Dialer
&aDialer
);
311 inline CommCbFunPtrCallT(const CommCbFunPtrCallT
&o
) :
312 AsyncCall(o
.debugSection
, o
.debugLevel
, o
.name
),
315 ~CommCbFunPtrCallT() {}
317 virtual CallDialer
* getDialer() { return &dialer
; }
323 inline virtual bool canFire();
324 inline virtual void fire();
327 CommCbFunPtrCallT
& operator=(const CommCbFunPtrCallT
&); // not defined. not permitted.
330 // Conveninece wrapper: It is often easier to call a templated function than
331 // to create a templated class.
332 template <class Dialer
>
334 CommCbFunPtrCallT
<Dialer
> *commCbCall(int debugSection
, int debugLevel
,
335 const char *callName
, const Dialer
&dialer
)
337 return new CommCbFunPtrCallT
<Dialer
>(debugSection
, debugLevel
, callName
,
341 /* inlined implementation of templated methods */
343 /* CommCbFunPtrCallT */
345 template <class Dialer
>
346 CommCbFunPtrCallT
<Dialer
>::CommCbFunPtrCallT(int aDebugSection
, int aDebugLevel
,
347 const char *callName
, const Dialer
&aDialer
):
348 AsyncCall(aDebugSection
, aDebugLevel
, callName
),
353 template <class Dialer
>
355 CommCbFunPtrCallT
<Dialer
>::canFire()
357 if (!AsyncCall::canFire())
360 if (!cbdataReferenceValid(dialer
.params
.data
))
361 return cancel("callee gone");
363 if (!dialer
.params
.syncWithComm())
364 return cancel("out of sync w/comm");
367 return cancel("no callback requested");
372 template <class Dialer
>
374 CommCbFunPtrCallT
<Dialer
>::fire()
379 #endif /* SQUID_COMMCALLS_H */