]> git.ipfire.org Git - thirdparty/squid.git/blob - src/base/AsyncJob.h
SourceLayout: Shuffle TextException into libbase
[thirdparty/squid.git] / src / base / AsyncJob.h
1 /*
2 * $Id$
3 */
4
5 #ifndef SQUID_ASYNC_JOB_H
6 #define SQUID_ASYNC_JOB_H
7
8 #include "base/AsyncCall.h"
9
10 /**
11 \defgroup AsyncJobAPI Async-Jobs API
12 \par
13 * AsyncJob is an API and a base for a class that implements a stand-alone
14 * "job", "task", or "logical processing thread" which receives asynchronous
15 * calls.
16 *
17 * Implementations should wrap each method receiving an asynchronous call in
18 * a pair of macros: AsyncCallEnter and AsyncCallExit. These macros:
19 * - provide call debugging
20 * - trap exceptions and terminate the task if an exception occurs
21 * - ensure that only one asynchronous call is active per object
22 * Most of the work is done by AsyncJob class methods. Macros just provide
23 * an enter/try/catch/exit framework.
24 *
25 * Eventually, the macros can and perhaps should be replaced with call/event
26 * processing code so that individual job classes do not have to wrap all
27 * asynchronous calls.
28 */
29
30 /// \ingroup AsyncJobAPI
31 class AsyncJob
32 {
33
34 public:
35 static AsyncJob *AsyncStart(AsyncJob *job); // use this to start jobs
36
37 AsyncJob(const char *aTypeName);
38 virtual ~AsyncJob();
39
40 virtual void *toCbdata() = 0;
41 void noteStart(); // calls virtual start
42
43 protected:
44 // XXX: temporary method to replace "delete this" in jobs-in-transition.
45 // Will be replaced with calls to mustStop() when transition is complete.
46 void deleteThis(const char *aReason);
47
48 void mustStop(const char *aReason); // force done() for a reason
49
50 bool done() const; // the job is destroyed in callEnd() when done()
51
52 virtual void start();
53 virtual bool doneAll() const; // return true when done
54 virtual void swanSong() {}; // perform internal cleanup
55 virtual const char *status() const; // for debugging
56
57 public:
58 // asynchronous call maintenance
59 bool canBeCalled(AsyncCall &call) const;
60 void callStart(AsyncCall &call);
61 virtual void callException(const std::exception &e);
62 virtual void callEnd();
63
64 protected:
65 const char *stopReason; // reason for forcing done() to be true
66 const char *typeName; // kid (leaf) class name, for debugging
67 AsyncCall::Pointer inCall; // the asynchronous call being handled, if any
68 const unsigned int id;
69
70 private:
71 static unsigned int TheLastId;
72 };
73
74
75 /**
76 \ingroup AsyncJobAPI
77 * This is a base class for all job call dialers. It does all the job
78 * dialing logic (debugging, handling exceptions, etc.) except for calling
79 * the job method. The latter is not possible without templates and we
80 * want to keep this class simple and template-free. Thus, we add a dial()
81 * virtual method that the JobCallT template below will implement for us,
82 * calling the job.
83 */
84 class JobDialer: public CallDialer
85 {
86 public:
87 JobDialer(AsyncJob *aJob);
88 JobDialer(const JobDialer &d);
89 virtual ~JobDialer();
90
91 virtual bool canDial(AsyncCall &call);
92 void dial(AsyncCall &call);
93
94 AsyncJob *job;
95 void *lock; // job's cbdata
96
97 protected:
98 virtual void doDial() = 0; // actually calls the job method
99
100 private:
101 // not implemented and should not be needed
102 JobDialer &operator =(const JobDialer &);
103 };
104
105 #include "base/AsyncJobCalls.h"
106
107 template <class Dialer>
108 bool
109 CallJob(int debugSection, int debugLevel, const char *fileName, int fileLine,
110 const char *callName, const Dialer &dialer)
111 {
112 AsyncCall::Pointer call = asyncCall(debugSection, debugLevel, callName, dialer);
113 return ScheduleCall(fileName, fileLine, call);
114 }
115
116
117 #define CallJobHere(debugSection, debugLevel, job, method) \
118 CallJob((debugSection), (debugLevel), __FILE__, __LINE__, #method, \
119 MemFun((job), &method))
120
121 #define CallJobHere1(debugSection, debugLevel, job, method, arg1) \
122 CallJob((debugSection), (debugLevel), __FILE__, __LINE__, #method, \
123 MemFun((job), &method, (arg1)))
124
125
126 #endif /* SQUID_ASYNC_JOB_H */