]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/base/AsyncJob.cc
11b2e6e3d614d63f92c9a2f1164040fa8ba7c71f
2 * Copyright (C) 1996-2022 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
9 /* DEBUG: section 93 ICAP (RFC 3507) Client */
12 #include "base/AsyncCall.h"
13 #include "base/AsyncJob.h"
14 #include "base/AsyncJobCalls.h"
15 #include "base/TextException.h"
21 InstanceIdDefinitions(AsyncJob
, "job");
24 AsyncJob::Start(const Pointer
&job
)
26 CallJobHere(93, 5, job
, AsyncJob
, start
);
27 job
->started_
= true; // it is the attempt that counts
30 AsyncJob::AsyncJob(const char *aTypeName
) :
31 stopReason(nullptr), typeName(aTypeName
), inCall(nullptr)
33 debugs(93,5, "AsyncJob constructed, this=" << this <<
34 " type=" << typeName
<< " [" << id
<< ']');
39 debugs(93,5, "AsyncJob destructed, this=" << this <<
40 " type=" << typeName
<< " [" << id
<< ']');
41 assert(!started_
|| swanSang_
);
44 void AsyncJob::start()
48 // XXX: temporary code to replace calls to "delete this" in jobs-in-transition.
49 // Will be replaced with calls to mustStop() when transition is complete.
50 void AsyncJob::deleteThis(const char *aReason
)
54 if (inCall
!= nullptr) {
55 // if we are in-call, then the call wrapper will delete us
56 debugs(93, 4, typeName
<< " will NOT delete in-call job, reason: " << stopReason
);
60 // there is no call wrapper waiting for our return, so we fake it
61 debugs(93, 5, typeName
<< " will delete this, reason: " << stopReason
);
62 CbcPointer
<AsyncJob
> self(this);
63 AsyncCall::Pointer fakeCall
= asyncCall(93,4, "FAKE-deleteThis",
64 JobMemFun(self
, &AsyncJob::deleteThis
, aReason
));
70 void AsyncJob::mustStop(const char *aReason
)
72 // XXX: temporary code to catch cases where mustStop is called outside
73 // of an async call context. Will be removed when that becomes impossible.
74 // Until then, this will cause memory leaks and possibly other problems.
77 debugs(93, 5, typeName
<< " will STALL, reason: " << stopReason
);
81 Must(inCall
!= nullptr); // otherwise nobody will delete us if we are done()
85 debugs(93, 5, typeName
<< " will stop, reason: " << stopReason
);
87 debugs(93, 5, typeName
<< " will stop, another reason: " << aReason
);
91 bool AsyncJob::done() const
93 // stopReason, set in mustStop(), overwrites all other conditions
94 return stopReason
!= nullptr || doneAll();
97 bool AsyncJob::doneAll() const
99 return true; // so that it is safe for kids to use
102 bool AsyncJob::canBeCalled(AsyncCall
&call
) const
104 if (inCall
!= nullptr) {
105 // This may happen when we have bugs or some module is not calling
106 // us asynchronously (comm used to do that).
107 debugs(93, 5, inCall
<< " is in progress; " <<
108 call
<< " cannot reenter the job.");
109 return call
.cancel("reentrant job call");
115 void AsyncJob::callStart(AsyncCall
&call
)
117 // we must be called asynchronously and hence, the caller must lock us
118 Must(cbdataReferenceValid(toCbdata()));
120 Must(!inCall
); // see AsyncJob::canBeCalled
122 inCall
= &call
; // XXX: ugly, but safe if callStart/callEnd,Ex are paired
123 debugs(inCall
->debugSection
, inCall
->debugLevel
,
124 typeName
<< " status in:" << status());
128 AsyncJob::callException(const std::exception
&ex
)
130 debugs(93, 2, ex
.what());
131 // we must be called asynchronously and hence, the caller must lock us
132 Must(cbdataReferenceValid(toCbdata()));
134 mustStop("exception");
137 void AsyncJob::callEnd()
140 debugs(93, 5, *inCall
<< " ends job" << status());
142 AsyncCall::Pointer inCallSaved
= inCall
;
143 void *thisSaved
= this;
145 // TODO: Swallow swanSong() exceptions to reduce memory leaks.
147 // Job callback invariant: swanSong() is (only) called for started jobs.
148 // Here to detect violations in kids that forgot to call our swanSong().
151 swanSang_
= true; // it is the attempt that counts
154 delete this; // this is the only place where a started job is deleted
156 // careful: this object does not exist any more
157 debugs(93, 6, *inCallSaved
<< " ended " << thisSaved
);
161 debugs(inCall
->debugSection
, inCall
->debugLevel
,
162 typeName
<< " status out:" << status());
166 // returns a temporary string depicting transaction status, for debugging
167 const char *AsyncJob::status() const
173 if (stopReason
!= nullptr) {
174 buf
.appendf("Stopped, reason:%s", stopReason
);
176 buf
.appendf(" %s%u]", id
.prefix(), id
.value
);
179 return buf
.content();