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