]> git.ipfire.org Git - thirdparty/squid.git/blob - src/adaptation/Initiate.cc
Removed assert(!theInitiator) from the destructor because that assertion fails
[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/Service.h"
8 #include "adaptation/Initiator.h"
9 #include "adaptation/Initiate.h"
10
11 namespace Adaptation {
12
13 // AdaptInitiator::noteAdaptionAnswer Dialer locks/unlocks the message in transit
14 // TODO: replace HTTPMSGLOCK with general RefCounting and delete this class
15 class AnswerDialer: public UnaryMemFunT<Initiator, HttpMsg*>
16 {
17 public:
18 typedef UnaryMemFunT<Initiator, HttpMsg*> Parent;
19
20 AnswerDialer(Initiator *obj, Parent::Method meth, HttpMsg *msg):
21 Parent(obj, meth, msg) { HTTPMSGLOCK(arg1); }
22 AnswerDialer(const AnswerDialer &d):
23 Parent(d) { HTTPMSGLOCK(arg1); }
24 virtual ~AnswerDialer() { HTTPMSGUNLOCK(arg1); }
25 };
26
27 } // namespace Adaptation
28
29
30 /* Initiate */
31
32 Adaptation::Initiate::Initiate(const char *aTypeName,
33 Initiator *anInitiator, ServicePointer aService):
34 AsyncJob(aTypeName), theInitiator(anInitiator), theService(aService)
35 {
36 assert(theService != NULL);
37 assert(theInitiator);
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 // internal cleanup
48 void Adaptation::Initiate::swanSong()
49 {
50 debugs(93, 5, HERE << "swan sings" << status());
51
52 if (theInitiator) {
53 debugs(93, 3, HERE << "fatal failure; sending abort notification");
54 tellQueryAborted(true); // final by default
55 }
56
57 debugs(93, 5, HERE << "swan sang" << status());
58 }
59
60 void Adaptation::Initiate::clearInitiator()
61 {
62 if (theInitiator)
63 theInitiator.clear();
64 }
65
66 void Adaptation::Initiate::sendAnswer(HttpMsg *msg)
67 {
68 assert(msg);
69 if (theInitiator.isThere()) {
70 CallJob(93, 5, __FILE__, __LINE__, "Initiator::noteAdaptAnswer",
71 AnswerDialer(theInitiator.ptr(), &Initiator::noteAdaptationAnswer, msg));
72 }
73 clearInitiator();
74 }
75
76
77 void Adaptation::Initiate::tellQueryAborted(bool final)
78 {
79 if (theInitiator.isThere()) {
80 CallJobHere1(93, 5, theInitiator.ptr(),
81 Initiator::noteAdaptationQueryAbort, final);
82 }
83 clearInitiator();
84 }
85
86 Adaptation::Service &
87 Adaptation::Initiate::service()
88 {
89 assert(theService != NULL);
90 return *theService;
91 }
92
93 const char *Adaptation::Initiate::status() const {
94 return ""; // for now
95 }
96
97
98 /* InitiatorHolder */
99
100 Adaptation::InitiatorHolder::InitiatorHolder(Initiator *anInitiator):
101 prime(0), cbdata(0)
102 {
103 if (anInitiator) {
104 cbdata = cbdataReference(anInitiator->toCbdata());
105 prime = anInitiator;
106 }
107 }
108
109 Adaptation::InitiatorHolder::InitiatorHolder(const InitiatorHolder &anInitiator):
110 prime(0), cbdata(0)
111 {
112 if (anInitiator != NULL && cbdataReferenceValid(anInitiator.cbdata)) {
113 cbdata = cbdataReference(anInitiator.cbdata);
114 prime = anInitiator.prime;
115 }
116 }
117
118 Adaptation::InitiatorHolder::~InitiatorHolder()
119 {
120 clear();
121 }
122
123 void Adaptation::InitiatorHolder::clear() {
124 if (prime) {
125 prime = NULL;
126 cbdataReferenceDone(cbdata);
127 }
128 }
129
130 Adaptation::Initiator *Adaptation::InitiatorHolder::ptr()
131 {
132 assert(isThere());
133 return prime;
134 }
135
136 bool
137 Adaptation::InitiatorHolder::isThere() {
138 return prime && cbdataReferenceValid(cbdata);
139 }
140
141 // should not be used
142 Adaptation::InitiatorHolder &
143 Adaptation::InitiatorHolder::operator =(const InitiatorHolder &anInitiator)
144 {
145 assert(false);
146 return *this;
147 }