]> git.ipfire.org Git - thirdparty/squid.git/blob - src/adaptation/Initiate.cc
Merge from trunk
[thirdparty/squid.git] / src / adaptation / Initiate.cc
1 /*
2 * DEBUG: section 93 ADAPT (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 assert(!theInitiator);
43 }
44
45 // internal cleanup
46 void Adaptation::Initiate::swanSong()
47 {
48 debugs(93, 5, HERE << "swan sings" << status());
49
50 if (theInitiator) {
51 debugs(93, 3, HERE << "fatal failure; sending abort notification");
52 tellQueryAborted(true); // final by default
53 }
54
55 debugs(93, 5, HERE << "swan sang" << status());
56 }
57
58 void Adaptation::Initiate::clearInitiator()
59 {
60 if (theInitiator)
61 theInitiator.clear();
62 }
63
64 void Adaptation::Initiate::sendAnswer(HttpMsg *msg)
65 {
66 assert(msg);
67 if (theInitiator.isThere()) {
68 CallJob(93, 5, __FILE__, __LINE__, "Initiator::noteAdaptAnswer",
69 AnswerDialer(theInitiator.ptr(), &Initiator::noteAdaptationAnswer, msg));
70 }
71 clearInitiator();
72 }
73
74
75 void Adaptation::Initiate::tellQueryAborted(bool final)
76 {
77 if (theInitiator.isThere()) {
78 CallJobHere1(93, 5, theInitiator.ptr(),
79 Initiator::noteAdaptationQueryAbort, final);
80 }
81 clearInitiator();
82 }
83
84 Adaptation::Service &
85 Adaptation::Initiate::service()
86 {
87 assert(theService != NULL);
88 return *theService;
89 }
90
91 const char *Adaptation::Initiate::status() const {
92 return ""; // for now
93 }
94
95
96 /* InitiatorHolder */
97
98 Adaptation::InitiatorHolder::InitiatorHolder(Initiator *anInitiator):
99 prime(0), cbdata(0)
100 {
101 if (anInitiator) {
102 cbdata = cbdataReference(anInitiator->toCbdata());
103 prime = anInitiator;
104 }
105 }
106
107 Adaptation::InitiatorHolder::InitiatorHolder(const InitiatorHolder &anInitiator):
108 prime(0), cbdata(0)
109 {
110 if (anInitiator != NULL && cbdataReferenceValid(anInitiator.cbdata)) {
111 cbdata = cbdataReference(anInitiator.cbdata);
112 prime = anInitiator.prime;
113 }
114 }
115
116 Adaptation::InitiatorHolder::~InitiatorHolder()
117 {
118 clear();
119 }
120
121 void Adaptation::InitiatorHolder::clear() {
122 if (prime) {
123 prime = NULL;
124 cbdataReferenceDone(cbdata);
125 }
126 }
127
128 Adaptation::Initiator *Adaptation::InitiatorHolder::ptr()
129 {
130 assert(isThere());
131 return prime;
132 }
133
134 bool
135 Adaptation::InitiatorHolder::isThere() {
136 return prime && cbdataReferenceValid(cbdata);
137 }
138
139 // should not be used
140 Adaptation::InitiatorHolder &
141 Adaptation::InitiatorHolder::operator =(const InitiatorHolder &anInitiator)
142 {
143 assert(false);
144 return *this;
145 }