]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ipc/Forwarder.cc
Maintenance: Consistent use of C++11 "override" specifier (#1224)
[thirdparty/squid.git] / src / ipc / Forwarder.cc
CommitLineData
51ea0904 1/*
bf95c10a 2 * Copyright (C) 1996-2022 The Squid Software Foundation and contributors
51ea0904 3 *
bbc27441
AJ
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.
51ea0904
CT
7 */
8
bbc27441
AJ
9/* DEBUG: section 54 Interprocess Communication */
10
f7f3304a 11#include "squid.h"
51ea0904
CT
12#include "base/AsyncJobCalls.h"
13#include "base/TextException.h"
1b76e6c1
AJ
14#include "errorpage.h"
15#include "HttpReply.h"
16#include "HttpRequest.h"
51ea0904
CT
17#include "ipc/Forwarder.h"
18#include "ipc/Port.h"
4c218615 19#include "ipc/RequestId.h"
51ea0904
CT
20#include "ipc/TypedMsgHdr.h"
21
51ea0904 22Ipc::Forwarder::RequestsMap Ipc::Forwarder::TheRequestsMap;
4c218615 23Ipc::RequestId::Index Ipc::Forwarder::LastRequestId = 0;
51ea0904
CT
24
25Ipc::Forwarder::Forwarder(Request::Pointer aRequest, double aTimeout):
f53969cc 26 AsyncJob("Ipc::Forwarder"),
87388f15 27 codeContext(CodeContext::Current()),
f53969cc 28 request(aRequest), timeout(aTimeout)
51ea0904 29{
51ea0904
CT
30}
31
32Ipc::Forwarder::~Forwarder()
33{
ebaabe74
AR
34 SWALLOW_EXCEPTIONS({
35 Must(request->requestId == 0);
36 });
51ea0904
CT
37}
38
39void
40Ipc::Forwarder::start()
41{
bf95c10a 42 debugs(54, 3, MYNAME);
51ea0904
CT
43
44 typedef NullaryMemFunT<Forwarder> Dialer;
933a6aed 45 AsyncCall::Pointer callback = JobCallback(54, 5, Dialer, this, Forwarder::handleRemoteAck);
51ea0904
CT
46 if (++LastRequestId == 0) // don't use zero value as request->requestId
47 ++LastRequestId;
48 request->requestId = LastRequestId;
49 TheRequestsMap[request->requestId] = callback;
50 TypedMsgHdr message;
51
52 try {
53 request->pack(message);
54 } catch (...) {
55 // assume the pack() call failed because the message did not fit
56 // TODO: add a more specific exception?
57 handleError();
a7ba2ec1 58 return;
51ea0904
CT
59 }
60
1ee292b7 61 SendMessage(Ipc::Port::CoordinatorAddr(), message);
51ea0904
CT
62 eventAdd("Ipc::Forwarder::requestTimedOut", &Forwarder::RequestTimedOut,
63 this, timeout, 0, false);
64}
65
66void
67Ipc::Forwarder::swanSong()
68{
bf95c10a 69 debugs(54, 5, MYNAME);
51ea0904
CT
70 removeTimeoutEvent();
71 if (request->requestId > 0) {
72 DequeueRequest(request->requestId);
73 request->requestId = 0;
74 }
51ea0904
CT
75}
76
77bool
78Ipc::Forwarder::doneAll() const
79{
bf95c10a 80 debugs(54, 5, MYNAME);
51ea0904
CT
81 return request->requestId == 0;
82}
83
84/// called when Coordinator starts processing the request
85void
86Ipc::Forwarder::handleRemoteAck()
87{
bf95c10a 88 debugs(54, 3, MYNAME);
51ea0904 89 request->requestId = 0;
70eb3fde
EB
90 // Do not do entry->complete() because it will trigger our client side
91 // processing when we no longer own the client-Squid connection.
92 // Let job cleanup close the client-Squid connection that Coordinator
93 // now owns.
51ea0904
CT
94}
95
96/// Ipc::Forwarder::requestTimedOut wrapper
97void
98Ipc::Forwarder::RequestTimedOut(void* param)
99{
bf95c10a 100 debugs(54, 3, MYNAME);
aee3523a 101 Must(param != nullptr);
51ea0904
CT
102 Forwarder* fwdr = static_cast<Forwarder*>(param);
103 // use async call to enable job call protection that time events lack
87388f15
EB
104
105 CallBack(fwdr->codeContext, [&fwdr] {
106 CallJobHere(54, 5, fwdr, Forwarder, requestTimedOut);
107 });
51ea0904
CT
108}
109
110/// called when Coordinator fails to start processing the request [in time]
111void
112Ipc::Forwarder::requestTimedOut()
113{
bf95c10a 114 debugs(54, 3, MYNAME);
51ea0904
CT
115 handleTimeout();
116}
117
118void
119Ipc::Forwarder::handleError()
120{
121 mustStop("error");
122}
123
124void
125Ipc::Forwarder::handleTimeout()
126{
127 mustStop("timeout");
128}
129
130/// terminate with an error
131void
132Ipc::Forwarder::handleException(const std::exception& e)
133{
bf95c10a 134 debugs(54, 3, e.what());
51ea0904
CT
135 mustStop("exception");
136}
137
138void
139Ipc::Forwarder::callException(const std::exception& e)
140{
141 try {
142 handleException(e);
143 } catch (const std::exception& ex) {
bf95c10a 144 debugs(54, DBG_CRITICAL, ex.what());
51ea0904
CT
145 }
146 AsyncJob::callException(e);
147}
148
149/// returns and forgets the right Forwarder callback for the request
150AsyncCall::Pointer
4c218615 151Ipc::Forwarder::DequeueRequest(const RequestId::Index requestId)
51ea0904 152{
bf95c10a 153 debugs(54, 3, MYNAME);
51ea0904
CT
154 Must(requestId != 0);
155 AsyncCall::Pointer call;
156 RequestsMap::iterator request = TheRequestsMap.find(requestId);
157 if (request != TheRequestsMap.end()) {
158 call = request->second;
aee3523a 159 Must(call != nullptr);
51ea0904
CT
160 TheRequestsMap.erase(request);
161 }
162 return call;
163}
164
165/// called when we are no longer waiting for Coordinator to respond
166void
167Ipc::Forwarder::removeTimeoutEvent()
168{
169 if (eventFind(&Forwarder::RequestTimedOut, this))
170 eventDelete(&Forwarder::RequestTimedOut, this);
171}
172
173void
4c218615 174Ipc::Forwarder::HandleRemoteAck(const RequestId requestId)
51ea0904 175{
bf95c10a 176 debugs(54, 3, MYNAME);
51ea0904
CT
177 Must(requestId != 0);
178
179 AsyncCall::Pointer call = DequeueRequest(requestId);
aee3523a 180 if (call != nullptr)
51ea0904
CT
181 ScheduleCallHere(call);
182}
f53969cc 183