]> git.ipfire.org Git - thirdparty/squid.git/blob - src/adaptation/Initiate.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / adaptation / Initiate.cc
1 /*
2 * DEBUG: section 93 ICAP (RFC 3507) Client
3 */
4
5 #include "squid.h"
6 #include "HttpMsg.h"
7 #include "adaptation/Answer.h"
8 #include "adaptation/Initiator.h"
9 #include "adaptation/Initiate.h"
10 #include "base/AsyncJobCalls.h"
11
12 namespace Adaptation
13 {
14 typedef UnaryMemFunT<Initiator, Answer, const Answer &> AnswerDialer;
15 /// Calls expectNoConsumption() if noteAdaptationAnswer async call is
16 /// scheduled but never fired (e.g., because the HTTP transaction aborts).
17 class AnswerCall: public AsyncCallT<AnswerDialer>
18 {
19 public:
20 AnswerCall(const char *aName, const AnswerDialer &aDialer) :
21 AsyncCallT<AnswerDialer>(93, 5, aName, aDialer), fired(false) {}
22 virtual void fire() {
23 fired = true;
24 AsyncCallT<AnswerDialer>::fire();
25 }
26 virtual ~AnswerCall() {
27 if (!fired && dialer.arg1.message != NULL && dialer.arg1.message->body_pipe != NULL)
28 dialer.arg1.message->body_pipe->expectNoConsumption();
29 }
30
31 private:
32 bool fired; ///< whether we fired the call
33 };
34 }
35
36 Adaptation::Initiate::Initiate(const char *aTypeName): AsyncJob(aTypeName)
37 {
38 }
39
40 Adaptation::Initiate::~Initiate()
41 {
42 // TODO: we cannot assert(!theInitiator) because that fails if a child
43 // constructor fails. AsyncJob should have wasStarted flag so that we
44 // can assert(!(wasStarted && theInitiator)).
45 }
46
47 void
48 Adaptation::Initiate::initiator(const CbcPointer<Initiator> &i)
49 {
50 Must(!theInitiator);
51 Must(i.valid());
52 theInitiator = i;
53 }
54
55
56 // internal cleanup
57 void Adaptation::Initiate::swanSong()
58 {
59 debugs(93, 5, HERE << "swan sings" << status());
60
61 if (theInitiator.set()) {
62 debugs(93, 3, HERE << "fatal failure; sending abort notification");
63 tellQueryAborted(true); // final by default
64 }
65
66 debugs(93, 5, HERE << "swan sang" << status());
67 }
68
69 void Adaptation::Initiate::clearInitiator()
70 {
71 theInitiator.clear();
72 }
73
74 void Adaptation::Initiate::sendAnswer(const Answer &answer)
75 {
76 AsyncCall::Pointer call = new AnswerCall("Initiator::noteAdaptationAnswer",
77 AnswerDialer(theInitiator, &Initiator::noteAdaptationAnswer, answer));
78 ScheduleCallHere(call);
79 clearInitiator();
80 }
81
82
83 void Adaptation::Initiate::tellQueryAborted(bool final)
84 {
85 sendAnswer(Answer::Error(final));
86 }
87
88 const char *Adaptation::Initiate::status() const
89 {
90 return AsyncJob::status(); // for now
91 }