]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/base/AsyncJobCalls.h
2 * Copyright (C) 1996-2014 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_ASYNCJOBCALLS_H
10 #define SQUID_ASYNCJOBCALLS_H
12 #include "base/AsyncJob.h"
13 #include "base/CbcPointer.h"
18 * This is a base class for all job call dialers. It does all the job
19 * dialing logic (debugging, handling exceptions, etc.) except for calling
20 * the job method. The latter requires knowing the number and type of method
21 * parameters. Thus, we add a dial() virtual method that the MemFunT templates
22 * below implement for us, calling the job's method with the right params.
25 class JobDialer
: public CallDialer
28 typedef Job DestClass
;
29 typedef CbcPointer
<Job
> JobPointer
;
31 JobDialer(const JobPointer
&aJob
);
32 JobDialer(const JobDialer
&d
);
34 virtual bool canDial(AsyncCall
&call
);
35 void dial(AsyncCall
&call
);
40 virtual void doDial() = 0; // actually calls the job method
43 // not implemented and should not be needed
44 JobDialer
&operator =(const JobDialer
&);
47 /// schedule an async job call using a dialer; use CallJobHere macros instead
48 template <class Dialer
>
50 CallJob(int debugSection
, int debugLevel
, const char *fileName
, int fileLine
,
51 const char *callName
, const Dialer
&dialer
)
53 AsyncCall::Pointer call
= asyncCall(debugSection
, debugLevel
, callName
, dialer
);
54 return ScheduleCall(fileName
, fileLine
, call
);
57 #define CallJobHere(debugSection, debugLevel, job, Class, method) \
58 CallJob((debugSection), (debugLevel), __FILE__, __LINE__, \
59 (#Class "::" #method), \
60 JobMemFun<Class>((job), &Class::method))
62 #define CallJobHere1(debugSection, debugLevel, job, Class, method, arg1) \
63 CallJob((debugSection), (debugLevel), __FILE__, __LINE__, \
64 (#Class "::" #method), \
65 JobMemFun((job), &Class::method, (arg1)))
67 /// Convenience macro to create a Dialer-based job callback
68 #define JobCallback(dbgSection, dbgLevel, Dialer, job, method) \
69 asyncCall((dbgSection), (dbgLevel), #method, \
70 Dialer(CbcPointer<Dialer::DestClass>(job), &method))
73 * *MemFunT are member function (i.e., class method) wrappers. They store
74 * details of a method call in an object so that the call can be delayed
75 * and executed asynchronously. Details may include the object pointer,
76 * the handler method pointer, and parameters. To simplify, we require
77 * all handlers to return void and not be constant.
81 * We need one wrapper for every supported member function arity (i.e.,
82 * number of handler arguments). The first template parameter is the class
83 * type of the handler. That class must be an AsyncJob child.
86 // Arity names are from http://en.wikipedia.org/wiki/Arity
89 class NullaryMemFunT
: public JobDialer
<Job
>
92 typedef void (Job::*Method
)();
93 explicit NullaryMemFunT(const CbcPointer
<Job
> &aJob
, Method aMethod
):
94 JobDialer
<Job
>(aJob
), method(aMethod
) {}
96 virtual void print(std::ostream
&os
) const { os
<< "()"; }
102 virtual void doDial() { ((&(*this->job
))->*method
)(); }
105 template <class Job
, class Data
, class Argument1
= Data
>
106 class UnaryMemFunT
: public JobDialer
<Job
>
109 typedef void (Job::*Method
)(Argument1
);
110 explicit UnaryMemFunT(const CbcPointer
<Job
> &aJob
, Method aMethod
,
111 const Data
&anArg1
): JobDialer
<Job
>(aJob
),
112 method(aMethod
), arg1(anArg1
) {}
114 virtual void print(std::ostream
&os
) const { os
<< '(' << arg1
<< ')'; }
121 virtual void doDial() { ((&(*this->job
))->*method
)(arg1
); }
124 // ... add more as needed
126 // Now we add global templated functions that create the member function
127 // wrappers above. These are for convenience: it is often easier to
128 // call a templated function than to create a templated object.
132 JobMemFun(const CbcPointer
<C
> &job
, typename NullaryMemFunT
<C
>::Method method
)
134 return NullaryMemFunT
<C
>(job
, method
);
137 template <class C
, class Argument1
>
138 UnaryMemFunT
<C
, Argument1
>
139 JobMemFun(const CbcPointer
<C
> &job
, typename UnaryMemFunT
<C
, Argument1
>::Method method
,
142 return UnaryMemFunT
<C
, Argument1
>(job
, method
, arg1
);
148 JobDialer
<Job
>::JobDialer(const JobPointer
&aJob
): job(aJob
)
153 JobDialer
<Job
>::JobDialer(const JobDialer
<Job
> &d
): CallDialer(d
), job(d
.job
)
159 JobDialer
<Job
>::canDial(AsyncCall
&call
)
162 return call
.cancel("job gone");
164 return job
->canBeCalled(call
);
169 JobDialer
<Job
>::dial(AsyncCall
&call
)
171 job
->callStart(call
);
175 } catch (const std::exception
&e
) {
176 debugs(call
.debugSection
, 3,
177 HERE
<< call
.name
<< " threw exception: " << e
.what());
178 job
->callException(e
);
181 job
->callEnd(); // may delete job
184 #endif /* SQUID_ASYNCJOBCALLS_H */