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_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 
25 template <class Job>
26 class JobDialer: public CallDialer
27 {
28 public:
29  typedef Job DestClass;
31 
32  JobDialer(const JobPointer &aJob);
33  JobDialer(const JobDialer &d);
34 
35  virtual bool canDial(AsyncCall &call);
36  void dial(AsyncCall &call);
37 
39 
40 protected:
41  virtual void doDial() = 0; // actually calls the job method
42 
43 private:
44  // not implemented and should not be needed
45  JobDialer &operator =(const JobDialer &);
46 };
47 
49 template <class Dialer>
51 CallJob(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 
90 template <class Job>
91 class NullaryMemFunT: public JobDialer<Job>
92 {
93 public:
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 
100 public:
102 
103 protected:
104  void doDial() override { ((&(*this->job))->*method)(); }
105 };
106 
107 template <class Job, class Data, class Argument1 = Data>
108 class UnaryMemFunT: public JobDialer<Job>
109 {
110 public:
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 
118 public:
120  Data arg1;
121 
122 protected:
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 
132 template <class C>
135 {
136  return NullaryMemFunT<C>(job, method);
137 }
138 
139 template <class C, class Argument1>
142  Argument1 arg1)
143 {
144  return UnaryMemFunT<C, Argument1>(job, method, arg1);
145 }
146 
147 // inlined methods
148 
149 template<class Job>
150 JobDialer<Job>::JobDialer(const JobPointer &aJob): job(aJob)
151 {
152 }
153 
154 template<class Job>
156 {
157 }
158 
159 template<class Job>
160 bool
162 {
163  if (!job)
164  return call.cancel("job gone");
165 
166  return job->canBeCalled(call);
167 }
168 
169 template<class Job>
170 void
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 cancel(const char *reason)
Definition: AsyncCall.cc:56
CbcPointer< Job > JobPointer
Definition: AsyncJobCalls.h:30
bool ScheduleCall(const char *fileName, int fileLine, const AsyncCall::Pointer &call)
Definition: AsyncCall.cc:94
#define Critical(id)
Definition: Messages.h:92
void doDial() override
void print(std::ostream &os) const override
Definition: AsyncJobCalls.h:98
JobDialer(const JobPointer &aJob)
void doDial() override
UnaryMemFunT(const CbcPointer< Job > &aJob, Method aMethod, const Data &anArg1)
void dial(AsyncCall &call)
void(Job::* Method)(Argument1)
JobDialer & operator=(const JobDialer &)
virtual bool canDial(AsyncCall &call)
RefCount< AsyncCallT< Dialer > > asyncCall(int aDebugSection, int aDebugLevel, const char *aName, const Dialer &aDialer)
Definition: AsyncCall.h:156
const int debugSection
Definition: AsyncCall.h:76
NullaryMemFunT< C > JobMemFun(const CbcPointer< C > &job, typename NullaryMemFunT< C >::Method method)
JobPointer job
Definition: AsyncJobCalls.h:38
void(Job::* Method)()
Definition: AsyncJobCalls.h:94
const char *const name
Definition: AsyncCall.h:71
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:51
virtual void doDial()=0
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:192
NullaryMemFunT(const CbcPointer< Job > &aJob, Method aMethod)
Definition: AsyncJobCalls.h:95
void print(std::ostream &os) const override

 

Introduction

Documentation

Support

Miscellaneous