]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/base/AsyncJob.cc
2 * DEBUG: section 93 ICAP (RFC 3507) Client
6 #include "base/AsyncCall.h"
7 #include "base/AsyncJob.h"
8 #include "base/TextException.h"
13 unsigned int AsyncJob::TheLastId
= 0;
15 AsyncJob
*AsyncJob::AsyncStart(AsyncJob
*job
)
18 CallJobHere(93, 5, job
, AsyncJob::noteStart
);
22 AsyncJob::AsyncJob(const char *aTypeName
): typeName(aTypeName
), inCall(NULL
), id(++TheLastId
)
24 debugs(93,3, "AsyncJob of type " << typeName
<< " constructed, this=" << this <<
25 " [async" << id
<< ']');
30 debugs(93,3, "AsyncJob of type " << typeName
<< " destructed, this=" << this <<
31 " [async" << id
<< ']');
34 void AsyncJob::noteStart()
39 void AsyncJob::start()
43 // XXX: temporary code to replace calls to "delete this" in jobs-in-transition.
44 // Will be replaced with calls to mustStop() when transition is complete.
45 void AsyncJob::deleteThis(const char *aReason
)
50 // if we are in-call, then the call wrapper will delete us
51 debugs(93, 4, typeName
<< " will NOT delete in-call job, reason: " << stopReason
);
55 // there is no call wrapper waiting for our return, so we fake it
56 debugs(93, 5, typeName
<< " will delete this, reason: " << stopReason
);
57 AsyncCall::Pointer fakeCall
= asyncCall(93,4, "FAKE-deleteThis",
58 MemFun(this, &AsyncJob::deleteThis
, aReason
));
64 void AsyncJob::mustStop(const char *aReason
)
66 // XXX: temporary code to catch cases where mustStop is called outside
67 // of an async call context. Will be removed when that becomes impossible.
68 // Until then, this will cause memory leaks and possibly other problems.
71 debugs(93, 5, typeName
<< " will STALL, reason: " << stopReason
);
75 Must(inCall
!= NULL
); // otherwise nobody will delete us if we are done()
79 debugs(93, 5, typeName
<< " will stop, reason: " << stopReason
);
81 debugs(93, 5, typeName
<< " will stop, another reason: " << aReason
);
85 bool AsyncJob::done() const
87 // stopReason, set in mustStop(), overwrites all other conditions
88 return stopReason
!= NULL
|| doneAll();
91 bool AsyncJob::doneAll() const
93 return true; // so that it is safe for kids to use
96 bool AsyncJob::canBeCalled(AsyncCall
&call
) const
99 // This may happen when we have bugs or some module is not calling
100 // us asynchronously (comm used to do that).
101 debugs(93, 5, HERE
<< inCall
<< " is in progress; " <<
102 call
<< " canot reenter the job.");
103 return call
.cancel("reentrant job call");
109 void AsyncJob::callStart(AsyncCall
&call
)
111 // we must be called asynchronously and hence, the caller must lock us
112 Must(cbdataReferenceValid(toCbdata()));
114 Must(!inCall
); // see AsyncJob::canBeCalled
116 inCall
= &call
; // XXX: ugly, but safe if callStart/callEnd,Ex are paired
117 debugs(inCall
->debugSection
, inCall
->debugLevel
,
118 typeName
<< " status in:" << status());
121 void AsyncJob::callException(const std::exception
&e
)
123 // we must be called asynchronously and hence, the caller must lock us
124 Must(cbdataReferenceValid(toCbdata()));
126 mustStop("exception");
129 void AsyncJob::callEnd()
132 debugs(93, 5, *inCall
<< " ends job" << status());
134 AsyncCall::Pointer inCallSaved
= inCall
;
135 void *thisSaved
= this;
139 delete this; // this is the only place where the object is deleted
141 // careful: this object does not exist any more
142 debugs(93, 6, HERE
<< *inCallSaved
<< " ended " << thisSaved
);
146 debugs(inCall
->debugSection
, inCall
->debugLevel
,
147 typeName
<< " status out:" << status());
151 // returns a temporary string depicting transaction status, for debugging
152 const char *AsyncJob::status() const
158 if (stopReason
!= NULL
) {
159 buf
.Printf("Stopped, reason:");
160 buf
.Printf("%s",stopReason
);
162 buf
.Printf(" job%d]", id
);
165 return buf
.content();
171 JobDialer::JobDialer(AsyncJob
*aJob
): job(NULL
), lock(NULL
)
174 lock
= cbdataReference(aJob
->toCbdata());
179 JobDialer::JobDialer(const JobDialer
&d
): CallDialer(d
),
180 job(NULL
), lock(NULL
)
182 if (d
.lock
&& cbdataReferenceValid(d
.lock
)) {
183 lock
= cbdataReference(d
.lock
);
189 JobDialer::~JobDialer()
191 cbdataReferenceDone(lock
); // lock may be NULL
196 JobDialer::canDial(AsyncCall
&call
)
199 return call
.cancel("job was gone before the call");
201 if (!cbdataReferenceValid(lock
))
202 return call
.cancel("job gone after the call");
205 return job
->canBeCalled(call
);
209 JobDialer::dial(AsyncCall
&call
)
211 Must(lock
&& cbdataReferenceValid(lock
)); // canDial() checks for this
214 job
->callStart(call
);
218 } catch (const std::exception
&e
) {
219 debugs(call
.debugSection
, 3,
220 HERE
<< call
.name
<< " threw exception: " << e
.what());
221 job
->callException(e
);
224 job
->callEnd(); // may delete job