1 #ifndef SQUID_COMMCALLS_H
2 #define SQUID_COMMCALLS_H
4 #include "base/AsyncCall.h"
5 #include "base/AsyncJobCalls.h"
6 #include "comm_err_t.h"
7 #include "comm/forward.h"
9 /* CommCalls implement AsyncCall interface for comm_* callbacks.
10 * The classes cover two call dialer kinds:
11 * - A C-style call using a function pointer (depricated);
12 * - A C++-style call to an AsyncJob child.
13 * and several comm_* callback kinds:
19 * and a special callback kind for passing pipe FD, disk FD or fd_table index 'FD' to the handler:
20 * - FD passing callback (FDECB)
23 class CommAcceptCbParams
;
24 typedef void IOACB(const CommAcceptCbParams
¶ms
);
26 typedef void CNCB(const Comm::ConnectionPointer
&conn
, comm_err_t status
, int xerrno
, void *data
);
27 typedef void IOCB(const Comm::ConnectionPointer
&conn
, char *, size_t size
, comm_err_t flag
, int xerrno
, void *data
);
29 class CommTimeoutCbParams
;
30 typedef void CTCB(const CommTimeoutCbParams
¶ms
);
32 class CommCloseCbParams
;
33 typedef void CLCB(const CommCloseCbParams
¶ms
);
36 typedef void FDECB(const FdeCbParams
¶ms
);
39 * TODO: When there are no function-pointer-based callbacks left, all
40 * this complexity can be removed. Jobs that need comm services will just
41 * implement CommReader, CommWriter, etc. interfaces and receive calls
42 * using general (not comm-specific) AsyncCall code. For now, we have to
43 * allow the caller to create a callback that comm can modify to set
44 * parameters, which is not trivial when the caller type/kind is not
45 * known to comm and there are many kinds of parameters.
48 /* Comm*CbParams classes below handle callback parameters */
50 // Maintains parameters common to all comm callbacks
51 class CommCommonCbParams
54 CommCommonCbParams(void *aData
);
55 CommCommonCbParams(const CommCommonCbParams
¶ms
);
56 ~CommCommonCbParams();
58 /// adjust using the current Comm state; returns false to cancel the call
59 // not virtual because callers know dialer type
60 bool syncWithComm() { return true; }
62 void print(std::ostream
&os
) const;
65 void *data
; // cbdata-protected
67 /** The connection which this call pertains to.
68 * \itemize On accept() calls this is the new client connection.
69 * \itemize On connect() finished calls this is the newely opened connection.
70 * \itemize On write calls this is the connection just written to.
71 * \itemize On read calls this is the connection just read from.
72 * \itemize On close calls this describes the connection which is now closed.
73 * \itemize On timeouts this is the connection whose operation timed out.
74 * NP: timeouts might also return to the connect/read/write handler with COMM_ERR_TIMEOUT.
76 Comm::ConnectionPointer conn
;
78 comm_err_t flag
; ///< comm layer result status.
79 int xerrno
; ///< The last errno to occur. non-zero if flag is COMM_ERR.
81 int fd
; ///< FD which the call was about. Set by the async call creator.
83 // should not be needed and not yet implemented
84 CommCommonCbParams
&operator =(const CommCommonCbParams
¶ms
);
88 class CommAcceptCbParams
: public CommCommonCbParams
91 CommAcceptCbParams(void *aData
);
95 class CommConnectCbParams
: public CommCommonCbParams
98 CommConnectCbParams(void *aData
);
100 bool syncWithComm(); // see CommCommonCbParams::syncWithComm
103 // read/write (I/O) parameters
104 class CommIoCbParams
: public CommCommonCbParams
107 CommIoCbParams(void *aData
);
109 void print(std::ostream
&os
) const;
110 bool syncWithComm(); // see CommCommonCbParams::syncWithComm
118 class CommCloseCbParams
: public CommCommonCbParams
121 CommCloseCbParams(void *aData
);
124 class CommTimeoutCbParams
: public CommCommonCbParams
127 CommTimeoutCbParams(void *aData
);
130 /// Special Calls parameter, for direct use of an FD without a controlling Comm::Connection
131 /// This is used for pipe() FD with helpers, and internally by Comm when handling some special FD actions.
132 class FdeCbParams
: public CommCommonCbParams
135 FdeCbParams(void *aData
);
136 // TODO make this a standalone object with FD value and pointer to fde table entry.
137 // that requires all the existing Comm handlers to be updated first though
140 // Interface to expose comm callback parameters of all comm dialers.
141 // GetCommParams() uses this interface to access comm parameters.
142 template <class Params_
>
143 class CommDialerParamsT
146 typedef Params_ Params
;
147 CommDialerParamsT(const Params
&io
): params(io
) {}
153 // Get comm params of an async comm call
154 template <class Params
>
155 Params
&GetCommParams(AsyncCall::Pointer
&call
)
157 typedef CommDialerParamsT
<Params
> DialerParams
;
158 DialerParams
*dp
= dynamic_cast<DialerParams
*>(call
->getDialer());
163 // All job dialers with comm parameters are merged into one since they
164 // all have exactly one callback argument and differ in Params type only
165 template <class C
, class Params_
>
166 class CommCbMemFunT
: public JobDialer
<C
>, public CommDialerParamsT
<Params_
>
169 typedef Params_ Params
;
170 typedef void (C::*Method
)(const Params
&io
);
172 CommCbMemFunT(const CbcPointer
<C
> &job
, Method meth
): JobDialer
<C
>(job
),
173 CommDialerParamsT
<Params_
>(job
.get()),
176 virtual bool canDial(AsyncCall
&c
) {
177 return JobDialer
<C
>::canDial(c
) &&
178 this->params
.syncWithComm();
181 virtual void print(std::ostream
&os
) const {
183 this->params
.print(os
);
191 virtual void doDial() { ((&(*this->job
))->*method
)(this->params
); }
194 // accept (IOACB) dialer
195 class CommAcceptCbPtrFun
: public CallDialer
,
196 public CommDialerParamsT
<CommAcceptCbParams
>
199 typedef CommAcceptCbParams Params
;
200 typedef RefCount
<CommAcceptCbPtrFun
> Pointer
;
202 CommAcceptCbPtrFun(IOACB
*aHandler
, const CommAcceptCbParams
&aParams
);
203 CommAcceptCbPtrFun(const CommAcceptCbPtrFun
&o
);
207 virtual void print(std::ostream
&os
) const;
213 // connect (CNCB) dialer
214 class CommConnectCbPtrFun
: public CallDialer
,
215 public CommDialerParamsT
<CommConnectCbParams
>
218 typedef CommConnectCbParams Params
;
220 CommConnectCbPtrFun(CNCB
*aHandler
, const Params
&aParams
);
223 virtual void print(std::ostream
&os
) const;
229 // read/write (IOCB) dialer
230 class CommIoCbPtrFun
: public CallDialer
,
231 public CommDialerParamsT
<CommIoCbParams
>
234 typedef CommIoCbParams Params
;
236 CommIoCbPtrFun(IOCB
*aHandler
, const Params
&aParams
);
239 virtual void print(std::ostream
&os
) const;
245 // close (CLCB) dialer
246 class CommCloseCbPtrFun
: public CallDialer
,
247 public CommDialerParamsT
<CommCloseCbParams
>
250 typedef CommCloseCbParams Params
;
252 CommCloseCbPtrFun(CLCB
*aHandler
, const Params
&aParams
);
255 virtual void print(std::ostream
&os
) const;
261 class CommTimeoutCbPtrFun
:public CallDialer
,
262 public CommDialerParamsT
<CommTimeoutCbParams
>
265 typedef CommTimeoutCbParams Params
;
267 CommTimeoutCbPtrFun(CTCB
*aHandler
, const Params
&aParams
);
270 virtual void print(std::ostream
&os
) const;
276 /// FD event (FDECB) dialer
277 class FdeCbPtrFun
: public CallDialer
,
278 public CommDialerParamsT
<FdeCbParams
>
281 typedef FdeCbParams Params
;
283 FdeCbPtrFun(FDECB
*aHandler
, const Params
&aParams
);
285 virtual void print(std::ostream
&os
) const;
291 // AsyncCall to comm handlers implemented as global functions.
292 // The dialer is one of the Comm*CbPtrFunT above
293 // TODO: Get rid of this class by moving canFire() to canDial() method
295 template <class Dialer
>
296 class CommCbFunPtrCallT
: public AsyncCall
299 typedef RefCount
<CommCbFunPtrCallT
<Dialer
> > Pointer
;
300 typedef typename
Dialer::Params Params
;
302 inline CommCbFunPtrCallT(int debugSection
, int debugLevel
,
303 const char *callName
, const Dialer
&aDialer
);
305 inline CommCbFunPtrCallT(const CommCbFunPtrCallT
&o
) :
306 AsyncCall(o
.debugSection
, o
.debugLevel
, o
.name
),
309 ~CommCbFunPtrCallT() {}
311 virtual CallDialer
* getDialer() { return &dialer
; }
317 inline virtual bool canFire();
318 inline virtual void fire();
321 CommCbFunPtrCallT
& operator=(const CommCbFunPtrCallT
&); // not defined. not permitted.
324 // Conveninece wrapper: It is often easier to call a templated function than
325 // to create a templated class.
326 template <class Dialer
>
328 CommCbFunPtrCallT
<Dialer
> *commCbCall(int debugSection
, int debugLevel
,
329 const char *callName
, const Dialer
&dialer
)
331 return new CommCbFunPtrCallT
<Dialer
>(debugSection
, debugLevel
, callName
,
335 /* inlined implementation of templated methods */
337 /* CommCbFunPtrCallT */
339 template <class Dialer
>
340 CommCbFunPtrCallT
<Dialer
>::CommCbFunPtrCallT(int aDebugSection
, int aDebugLevel
,
341 const char *callName
, const Dialer
&aDialer
):
342 AsyncCall(aDebugSection
, aDebugLevel
, callName
),
347 template <class Dialer
>
349 CommCbFunPtrCallT
<Dialer
>::canFire()
351 if (!AsyncCall::canFire())
354 if (!cbdataReferenceValid(dialer
.params
.data
))
355 return cancel("callee gone");
357 if (!dialer
.params
.syncWithComm())
358 return cancel("out of sync w/comm");
361 return cancel("no callback requested");
366 template <class Dialer
>
368 CommCbFunPtrCallT
<Dialer
>::fire()
373 #endif /* SQUID_COMMCALLS_H */