Squid Web Cache master
Loading...
Searching...
No Matches
AsyncJobCalls.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2025 The Squid Software Foundation and contributors
3 *
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.
7 */
8
9#ifndef SQUID_SRC_BASE_ASYNCJOBCALLS_H
10#define SQUID_SRC_BASE_ASYNCJOBCALLS_H
11
12#include "base/AsyncJob.h"
13#include "base/CbcPointer.h"
14#include "debug/Messages.h"
15#include "debug/Stream.h"
16
25template <class Job>
26class JobDialer: public CallDialer
27{
28public:
29 typedef Job DestClass;
31
32 JobDialer(const JobPointer &aJob);
34
35 virtual bool canDial(AsyncCall &call);
36 void dial(AsyncCall &call);
37
39
40protected:
41 virtual void doDial() = 0; // actually calls the job method
42
43private:
44 // not implemented and should not be needed
46};
47
49template <class Dialer>
51CallJob(int debugSection, int debugLevel, const char *fileName, int fileLine,
52 const char *callName, const Dialer &dialer)
53{
54 AsyncCall::Pointer call = asyncCall(debugSection, debugLevel, callName, dialer);
55 ScheduleCall(fileName, fileLine, call);
56 return call;
57}
58
59#define CallJobHere(debugSection, debugLevel, job, Class, method) \
60 CallJob((debugSection), (debugLevel), __FILE__, __LINE__, \
61 (#Class "::" #method), \
62 JobMemFun<Class>((job), &Class::method))
63
64#define CallJobHere1(debugSection, debugLevel, job, Class, method, arg1) \
65 CallJob((debugSection), (debugLevel), __FILE__, __LINE__, \
66 (#Class "::" #method), \
67 JobMemFun((job), &Class::method, (arg1)))
68
70#define JobCallback(dbgSection, dbgLevel, Dialer, job, method) \
71 asyncCall((dbgSection), (dbgLevel), #method, \
72 Dialer(CbcPointer<Dialer::DestClass>(job), &method))
73
74/*
75 * *MemFunT are member function (i.e., class method) wrappers. They store
76 * details of a method call in an object so that the call can be delayed
77 * and executed asynchronously. Details may include the object pointer,
78 * the handler method pointer, and parameters. To simplify, we require
79 * all handlers to return void and not be constant.
80 */
81
82/*
83 * We need one wrapper for every supported member function arity (i.e.,
84 * number of handler arguments). The first template parameter is the class
85 * type of the handler. That class must be an AsyncJob child.
86 */
87
88// Arity names are from http://en.wikipedia.org/wiki/Arity
89
90template <class Job>
91class NullaryMemFunT: public JobDialer<Job>
92{
93public:
94 typedef void (Job::*Method)();
95 explicit NullaryMemFunT(const CbcPointer<Job> &aJob, Method aMethod):
96 JobDialer<Job>(aJob), method(aMethod) {}
97
98 void print(std::ostream &os) const override { os << "()"; }
99
100public:
102
103protected:
104 void doDial() override { ((&(*this->job))->*method)(); }
105};
106
107template <class Job, class Data, class Argument1 = Data>
108class UnaryMemFunT: public JobDialer<Job>
109{
110public:
111 typedef void (Job::*Method)(Argument1);
112 explicit UnaryMemFunT(const CbcPointer<Job> &aJob, Method aMethod,
113 const Data &anArg1): JobDialer<Job>(aJob),
114 method(aMethod), arg1(anArg1) {}
115
116 void print(std::ostream &os) const override { os << '(' << arg1 << ')'; }
117
118public:
120 Data arg1;
121
122protected:
123 void doDial() override { ((&(*this->job))->*method)(arg1); }
124};
125
126// ... add more as needed
127
128// Now we add global templated functions that create the member function
129// wrappers above. These are for convenience: it is often easier to
130// call a templated function than to create a templated object.
131
132template <class C>
135{
136 return NullaryMemFunT<C>(job, method);
137}
138
139template <class C, class Argument1>
142 Argument1 arg1)
143{
144 return UnaryMemFunT<C, Argument1>(job, method, arg1);
145}
146
147// inlined methods
148
149template<class Job>
151{
152}
153
154template<class Job>
156{
157}
158
159template<class Job>
160bool
162{
163 if (!job)
164 return call.cancel("job gone");
165
166 return job->canBeCalled(call);
167}
168
169template<class Job>
170void
172{
173 job->callStart(call);
174
175 try {
176 doDial();
177 } catch (const std::exception &e) {
178 debugs(call.debugSection, 3,
179 call.name << " threw exception: " << e.what());
180 if (!job) {
181 debugs(call.debugSection, Critical(70), "ERROR: Squid BUG: Job invalidated during " <<
182 call.name << " that threw exception: " << e.what());
183 return; // see also: bug 4981, commit e3b6f15, and XXX in Http::Stream class description
184 }
185 job->callException(e);
186 }
187
188 if (!job) {
189 debugs(call.debugSection, Critical(71), "ERROR: Squid BUG: Job invalidated during " << call.name);
190 return;
191 }
192 job->callEnd(); // may delete job
193}
194
195#endif /* SQUID_SRC_BASE_ASYNCJOBCALLS_H */
196
bool ScheduleCall(const char *fileName, int fileLine, const AsyncCall::Pointer &call)
Definition AsyncCall.cc:94
RefCount< AsyncCallT< Dialer > > asyncCall(int aDebugSection, int aDebugLevel, const char *aName, const Dialer &aDialer)
Definition AsyncCall.h:156
NullaryMemFunT< C > JobMemFun(const CbcPointer< C > &job, typename NullaryMemFunT< C >::Method method)
AsyncCall::Pointer CallJob(int debugSection, int debugLevel, const char *fileName, int fileLine, const char *callName, const Dialer &dialer)
schedule an async job call using a dialer; use CallJobHere macros instead
bool cancel(const char *reason)
Definition AsyncCall.cc:56
const int debugSection
Definition AsyncCall.h:76
const char *const name
Definition AsyncCall.h:71
virtual void doDial()=0
virtual bool canDial(AsyncCall &call)
JobDialer(const JobDialer &d)
void dial(AsyncCall &call)
JobDialer(const JobPointer &aJob)
JobPointer job
JobDialer & operator=(const JobDialer &)
CbcPointer< Job > JobPointer
NullaryMemFunT(const CbcPointer< Job > &aJob, Method aMethod)
void print(std::ostream &os) const override
void(Job::* Method)()
void doDial() override
void print(std::ostream &os) const override
UnaryMemFunT(const CbcPointer< Job > &aJob, Method aMethod, const Data &anArg1)
void doDial() override
void(Job::* Method)(Argument1)
#define Critical(id)
Definition Messages.h:92
#define debugs(SECTION, LEVEL, CONTENT)
Definition Stream.h:192