5
#ifndef SQUID_ASYNCCALL_H
6
#define SQUID_ASYNCCALL_H
10
//#include "TextException.h"
13
\defgroup AsynCallsAPI Async-Calls API
15
* A call is asynchronous if the caller proceeds after the call is made,
16
* and the callee receives the call during the next main loop iteration.
17
* Asynchronous calls help avoid nasty call-me-when-I-call-you loops
18
* that humans often have trouble understanding or implementing correctly.
20
* Asynchronous calls are currently implemented via Squid events. The call
21
* event stores the pointer to the callback function and cbdata-protected
22
* callback data. To call a method of an object, the method is wrapped
23
* in a method-specific, static callback function and the pointer to the
24
* object is passed to the wrapper. For the method call to be safe, the
25
* class must be cbdata-enabled.
27
* You do not have to use the macros below to make or receive asynchronous
28
* method calls, but they give you a uniform interface and handy call
36
\todo add unique call IDs
37
\todo CBDATA_CLASS2 kids
38
\ingroup AsyncCallsAPI
40
class AsyncCall: public RefCountable
43
typedef RefCount <AsyncCall> Pointer;
44
friend class AsyncCallQueue;
46
AsyncCall(int aDebugSection, int aDebugLevel, const char *aName);
49
void make(); // fire if we can; handles general call debugging
51
// can be called from canFire() for debugging; always returns false
52
bool cancel(const char *reason);
54
bool canceled() { return isCanceled != NULL; }
56
virtual CallDialer *getDialer() = 0;
58
void print(std::ostream &os);
60
void setNext(AsyncCall::Pointer aNext) {
64
AsyncCall::Pointer &Next() {
69
const char *const name;
70
const int debugSection;
72
const unsigned int id;
75
virtual bool canFire();
77
virtual void fire() = 0;
79
AsyncCall::Pointer theNext; // used exclusively by AsyncCallQueue
82
const char *isCanceled; // set to the cancelation reason by cancel()
83
static unsigned int TheLastId;
87
std::ostream &operator <<(std::ostream &os, AsyncCall &call)
95
* Interface for all async call dialers
101
virtual ~CallDialer() {}
103
// TODO: Add these for clarity when CommCbFunPtrCallT is gone
104
//virtual bool canDial(AsyncCall &call) = 0;
105
//virtual void dial(AsyncCall &call) = 0;
107
virtual void print(std::ostream &os) const = 0;
111
\ingroup AsyncCallAPI
112
* This template implements an AsyncCall using a specified Dialer class
114
template <class Dialer>
115
class AsyncCallT: public AsyncCall
118
AsyncCallT(int aDebugSection, int aDebugLevel, const char *aName,
119
const Dialer &aDialer): AsyncCall(aDebugSection, aDebugLevel, aName),
122
CallDialer *getDialer() { return &dialer; }
125
virtual bool canFire() {
126
return AsyncCall::canFire() &&
127
dialer.canDial(*this);
129
virtual void fire() { dialer.dial(*this); }
134
template <class Dialer>
137
asyncCall(int aDebugSection, int aDebugLevel, const char *aName,
138
const Dialer &aDialer)
140
return new AsyncCallT<Dialer>(aDebugSection, aDebugLevel, aName, aDialer);
143
/** Call scheduling helper. Use ScheduleCallHere if you can. */
144
extern bool ScheduleCall(const char *fileName, int fileLine, AsyncCall::Pointer &call);
146
/** Call scheduling helper. */
147
#define ScheduleCallHere(call) ScheduleCall(__FILE__, __LINE__, (call))
150
#endif /* SQUID_ASYNCCALL_H */