]> git.ipfire.org Git - thirdparty/squid.git/blame - src/AsyncCall.h
Updates for running on squid-cache.org
[thirdparty/squid.git] / src / AsyncCall.h
CommitLineData
854d4d81 1/*
63be0a78 2 * $Id: AsyncCall.h,v 1.4 2008/02/26 21:49:34 amosjeffries Exp $
854d4d81 3 */
4
5#ifndef SQUID_ASYNCCALL_H
6#define SQUID_ASYNCCALL_H
7
8//#include "cbdata.h"
9#include "event.h"
3e5c8cf4 10//#include "TextException.h"
854d4d81 11
63be0a78 12/**
13 \defgroup AsynCallsAPI Async-Calls API
14 \par
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.
19 \par
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.
26 \par
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
29 * debugging.
30 */
854d4d81 31
3e5c8cf4 32class CallDialer;
33class AsyncCallQueue;
34
63be0a78 35/**
36 \todo add unique call IDs
37 \todo CBDATA_CLASS2 kids
38 \ingroup AsyncCallsAPI
39 */
3e5c8cf4 40class AsyncCall: public RefCountable
41{
42public:
43 typedef RefCount <AsyncCall> Pointer;
44 friend class AsyncCallQueue;
45
46 AsyncCall(int aDebugSection, int aDebugLevel, const char *aName);
47 virtual ~AsyncCall();
48
49 void make(); // fire if we can; handles general call debugging
50
51 // can be called from canFire() for debugging; always returns false
52 bool cancel(const char *reason);
53
54 bool canceled() { return isCanceled != NULL; }
55
56 virtual CallDialer *getDialer() = 0;
57
58 void print(std::ostream &os);
59
60 void setNext(AsyncCall::Pointer aNext) {
61 theNext = aNext;
62 }
63
64 AsyncCall::Pointer &Next() {
65 return theNext;
66 }
67
68public:
69 const char *const name;
70 const int debugSection;
71 const int debugLevel;
72 const unsigned int id;
73
74protected:
75 virtual bool canFire();
76
77 virtual void fire() = 0;
78
79 AsyncCall::Pointer theNext; // used exclusively by AsyncCallQueue
80
81private:
82 const char *isCanceled; // set to the cancelation reason by cancel()
83 static unsigned int TheLastId;
84};
85
86inline
87std::ostream &operator <<(std::ostream &os, AsyncCall &call)
88{
89 call.print(os);
90 return os;
854d4d81 91}
92
63be0a78 93/**
94 \ingroup AsyncCallAPI
95 * Interface for all async call dialers
96 */
3e5c8cf4 97class CallDialer
98{
99public:
100 CallDialer() {}
101 virtual ~CallDialer() {}
102
103 // TODO: Add these for clarity when CommCbFunPtrCallT is gone
104 //virtual bool canDial(AsyncCall &call) = 0;
105 //virtual void dial(AsyncCall &call) = 0;
106
107 virtual void print(std::ostream &os) const = 0;
108};
109
63be0a78 110/**
111 \ingroup AsyncCallAPI
112 * This template implements an AsyncCall using a specified Dialer class
113 */
3e5c8cf4 114template <class Dialer>
115class AsyncCallT: public AsyncCall
116{
117public:
118 AsyncCallT(int aDebugSection, int aDebugLevel, const char *aName,
119 const Dialer &aDialer): AsyncCall(aDebugSection, aDebugLevel, aName),
120 dialer(aDialer) {}
121
122 CallDialer *getDialer() { return &dialer; }
123
124protected:
125 virtual bool canFire() { return AsyncCall::canFire() &&
126 dialer.canDial(*this); }
127 virtual void fire() { dialer.dial(*this); }
128
129 Dialer dialer;
130};
131
132template <class Dialer>
133inline
134AsyncCall *
135asyncCall(int aDebugSection, int aDebugLevel, const char *aName,
136 const Dialer &aDialer)
137{
138 return new AsyncCallT<Dialer>(aDebugSection, aDebugLevel, aName, aDialer);
139}
854d4d81 140
63be0a78 141/** Call scheduling helper. Use ScheduleCallHere if you can. */
3e5c8cf4 142extern bool ScheduleCall(const char *fileName, int fileLine, AsyncCall::Pointer &call);
63be0a78 143
144/** Call scheduling helper. */
3e5c8cf4 145#define ScheduleCallHere(call) ScheduleCall(__FILE__, __LINE__, (call))
854d4d81 146
147
148#endif /* SQUID_ASYNCCALL_H */