]>
Commit | Line | Data |
---|---|---|
2e4a5466 | 1 | /* |
b510f3a1 | 2 | * DEBUG: section 93 ICAP (RFC 3507) Client |
2e4a5466 AR |
3 | */ |
4 | ||
f7f3304a | 5 | #include "squid-old.h" |
2e4a5466 | 6 | #include "HttpMsg.h" |
1adcebc3 | 7 | #include "adaptation/Answer.h" |
2e4a5466 AR |
8 | #include "adaptation/Initiator.h" |
9 | #include "adaptation/Initiate.h" | |
4299f876 | 10 | #include "base/AsyncJobCalls.h" |
2e4a5466 | 11 | |
1733bbba CT |
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). | |
a9336c23 A |
17 | class AnswerCall: public AsyncCallT<AnswerDialer> |
18 | { | |
1733bbba CT |
19 | public: |
20 | AnswerCall(const char *aName, const AnswerDialer &aDialer) : | |
a9336c23 | 21 | AsyncCallT<AnswerDialer>(93, 5, aName, aDialer), fired(false) {} |
1733bbba | 22 | virtual void fire() { |
a9336c23 | 23 | fired = true; |
1733bbba CT |
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 | } | |
2e4a5466 | 35 | |
4299f876 | 36 | Adaptation::Initiate::Initiate(const char *aTypeName): AsyncJob(aTypeName) |
2e4a5466 | 37 | { |
2e4a5466 AR |
38 | } |
39 | ||
40 | Adaptation::Initiate::~Initiate() | |
41 | { | |
b8af5c82 AR |
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)). | |
2e4a5466 AR |
45 | } |
46 | ||
4299f876 AR |
47 | void |
48 | Adaptation::Initiate::initiator(const CbcPointer<Initiator> &i) | |
49 | { | |
50 | Must(!theInitiator); | |
51 | Must(i.valid()); | |
52 | theInitiator = i; | |
53 | } | |
54 | ||
55 | ||
2e4a5466 AR |
56 | // internal cleanup |
57 | void Adaptation::Initiate::swanSong() | |
58 | { | |
59 | debugs(93, 5, HERE << "swan sings" << status()); | |
60 | ||
4299f876 | 61 | if (theInitiator.set()) { |
2e4a5466 AR |
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 | { | |
4299f876 | 71 | theInitiator.clear(); |
2e4a5466 AR |
72 | } |
73 | ||
3af10ac0 | 74 | void Adaptation::Initiate::sendAnswer(const Answer &answer) |
2e4a5466 | 75 | { |
1733bbba | 76 | AsyncCall::Pointer call = new AnswerCall("Initiator::noteAdaptationAnswer", |
a9336c23 | 77 | AnswerDialer(theInitiator, &Initiator::noteAdaptationAnswer, answer)); |
1733bbba | 78 | ScheduleCallHere(call); |
2e4a5466 AR |
79 | clearInitiator(); |
80 | } | |
81 | ||
82 | ||
83 | void Adaptation::Initiate::tellQueryAborted(bool final) | |
84 | { | |
3af10ac0 | 85 | sendAnswer(Answer::Error(final)); |
2e4a5466 AR |
86 | } |
87 | ||
26ac0430 AJ |
88 | const char *Adaptation::Initiate::status() const |
89 | { | |
a0b91cde | 90 | return AsyncJob::status(); // for now |
2e4a5466 | 91 | } |