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

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors