]>
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/AsyncJobCalls.h"
9 #include "base/TextException.h"
14 unsigned int AsyncJob::TheLastId
= 0;
16 AsyncJob::Pointer
AsyncJob::Start(AsyncJob
*j
)
18 AsyncJob::Pointer
job(j
);
19 CallJobHere(93, 5, job
, AsyncJob
, start
);
23 AsyncJob::AsyncJob(const char *aTypeName
): typeName(aTypeName
), inCall(NULL
), id(++TheLastId
)
25 debugs(93,3, "AsyncJob of type " << typeName
<< " constructed, this=" << this <<
26 " [async" << id
<< ']');
31 debugs(93,3, "AsyncJob of type " << typeName
<< " destructed, this=" << this <<
32 " [async" << id
<< ']');
35 void AsyncJob::start()
39 // XXX: temporary code to replace calls to "delete this" in jobs-in-transition.
40 // Will be replaced with calls to mustStop() when transition is complete.
41 void AsyncJob::deleteThis(const char *aReason
)
46 // if we are in-call, then the call wrapper will delete us
47 debugs(93, 4, typeName
<< " will NOT delete in-call job, reason: " << stopReason
);
51 // there is no call wrapper waiting for our return, so we fake it
52 debugs(93, 5, typeName
<< " will delete this, reason: " << stopReason
);
53 CbcPointer
<AsyncJob
> self(this);
54 AsyncCall::Pointer fakeCall
= asyncCall(93,4, "FAKE-deleteThis",
55 JobMemFun(self
, &AsyncJob::deleteThis
, aReason
));
61 void AsyncJob::mustStop(const char *aReason
)
63 // XXX: temporary code to catch cases where mustStop is called outside
64 // of an async call context. Will be removed when that becomes impossible.
65 // Until then, this will cause memory leaks and possibly other problems.
68 debugs(93, 5, typeName
<< " will STALL, reason: " << stopReason
);
72 Must(inCall
!= NULL
); // otherwise nobody will delete us if we are done()
76 debugs(93, 5, typeName
<< " will stop, reason: " << stopReason
);
78 debugs(93, 5, typeName
<< " will stop, another reason: " << aReason
);
82 bool AsyncJob::done() const
84 // stopReason, set in mustStop(), overwrites all other conditions
85 return stopReason
!= NULL
|| doneAll();
88 bool AsyncJob::doneAll() const
90 return true; // so that it is safe for kids to use
93 bool AsyncJob::canBeCalled(AsyncCall
&call
) const
96 // This may happen when we have bugs or some module is not calling
97 // us asynchronously (comm used to do that).
98 debugs(93, 5, HERE
<< inCall
<< " is in progress; " <<
99 call
<< " canot reenter the job.");
100 return call
.cancel("reentrant job call");
106 void AsyncJob::callStart(AsyncCall
&call
)
108 // we must be called asynchronously and hence, the caller must lock us
109 Must(cbdataReferenceValid(toCbdata()));
111 Must(!inCall
); // see AsyncJob::canBeCalled
113 inCall
= &call
; // XXX: ugly, but safe if callStart/callEnd,Ex are paired
114 debugs(inCall
->debugSection
, inCall
->debugLevel
,
115 typeName
<< " status in:" << status());
118 void AsyncJob::callException(const std::exception
&e
)
120 // we must be called asynchronously and hence, the caller must lock us
121 Must(cbdataReferenceValid(toCbdata()));
123 mustStop("exception");
126 void AsyncJob::callEnd()
129 debugs(93, 5, *inCall
<< " ends job" << status());
131 AsyncCall::Pointer inCallSaved
= inCall
;
132 void *thisSaved
= this;
136 delete this; // this is the only place where the object is deleted
138 // careful: this object does not exist any more
139 debugs(93, 6, HERE
<< *inCallSaved
<< " ended " << thisSaved
);
143 debugs(inCall
->debugSection
, inCall
->debugLevel
,
144 typeName
<< " status out:" << status());
148 // returns a temporary string depicting transaction status, for debugging
149 const char *AsyncJob::status() const
155 if (stopReason
!= NULL
) {
156 buf
.Printf("Stopped, reason:");
157 buf
.Printf("%s",stopReason
);
159 buf
.Printf(" job%d]", id
);
162 return buf
.content();