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