]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/ipc/Forwarder.cc
2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
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.
9 /* DEBUG: section 54 Interprocess Communication */
12 #include "base/AsyncJobCalls.h"
13 #include "base/TextException.h"
14 #include "errorpage.h"
15 #include "HttpReply.h"
16 #include "HttpRequest.h"
17 #include "ipc/Forwarder.h"
19 #include "ipc/RequestId.h"
20 #include "ipc/TypedMsgHdr.h"
22 Ipc::Forwarder::RequestsMap
Ipc::Forwarder::TheRequestsMap
;
23 Ipc::RequestId::Index
Ipc::Forwarder::LastRequestId
= 0;
25 Ipc::Forwarder::Forwarder(Request::Pointer aRequest
, double aTimeout
):
26 AsyncJob("Ipc::Forwarder"),
27 codeContext(CodeContext::Current()),
28 request(aRequest
), timeout(aTimeout
)
32 Ipc::Forwarder::~Forwarder()
35 Must(request
->requestId
== 0);
40 Ipc::Forwarder::start()
42 debugs(54, 3, MYNAME
);
44 typedef NullaryMemFunT
<Forwarder
> Dialer
;
45 AsyncCall::Pointer callback
= JobCallback(54, 5, Dialer
, this, Forwarder::handleRemoteAck
);
46 if (++LastRequestId
== 0) // don't use zero value as request->requestId
48 request
->requestId
= LastRequestId
;
49 TheRequestsMap
[request
->requestId
] = callback
;
53 request
->pack(message
);
55 // assume the pack() call failed because the message did not fit
56 // TODO: add a more specific exception?
61 SendMessage(Ipc::Port::CoordinatorAddr(), message
);
62 eventAdd("Ipc::Forwarder::requestTimedOut", &Forwarder::RequestTimedOut
,
63 this, timeout
, 0, false);
67 Ipc::Forwarder::swanSong()
69 debugs(54, 5, MYNAME
);
71 if (request
->requestId
> 0) {
72 DequeueRequest(request
->requestId
);
73 request
->requestId
= 0;
78 Ipc::Forwarder::doneAll() const
80 debugs(54, 5, MYNAME
);
81 return request
->requestId
== 0;
84 /// called when Coordinator starts processing the request
86 Ipc::Forwarder::handleRemoteAck()
88 debugs(54, 3, MYNAME
);
89 request
->requestId
= 0;
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
96 /// Ipc::Forwarder::requestTimedOut wrapper
98 Ipc::Forwarder::RequestTimedOut(void* param
)
100 debugs(54, 3, MYNAME
);
101 Must(param
!= nullptr);
102 Forwarder
* fwdr
= static_cast<Forwarder
*>(param
);
103 // use async call to enable job call protection that time events lack
105 CallBack(fwdr
->codeContext
, [&fwdr
] {
106 CallJobHere(54, 5, fwdr
, Forwarder
, requestTimedOut
);
110 /// called when Coordinator fails to start processing the request [in time]
112 Ipc::Forwarder::requestTimedOut()
114 debugs(54, 3, MYNAME
);
119 Ipc::Forwarder::handleError()
125 Ipc::Forwarder::handleTimeout()
130 /// terminate with an error
132 Ipc::Forwarder::handleException(const std::exception
& e
)
134 debugs(54, 3, e
.what());
135 mustStop("exception");
139 Ipc::Forwarder::callException(const std::exception
& e
)
143 } catch (const std::exception
& ex
) {
144 debugs(54, DBG_CRITICAL
, ex
.what());
146 AsyncJob::callException(e
);
149 /// returns and forgets the right Forwarder callback for the request
151 Ipc::Forwarder::DequeueRequest(const RequestId::Index requestId
)
153 debugs(54, 3, MYNAME
);
154 Must(requestId
!= 0);
155 AsyncCall::Pointer call
;
156 RequestsMap::iterator request
= TheRequestsMap
.find(requestId
);
157 if (request
!= TheRequestsMap
.end()) {
158 call
= request
->second
;
159 Must(call
!= nullptr);
160 TheRequestsMap
.erase(request
);
165 /// called when we are no longer waiting for Coordinator to respond
167 Ipc::Forwarder::removeTimeoutEvent()
169 if (eventFind(&Forwarder::RequestTimedOut
, this))
170 eventDelete(&Forwarder::RequestTimedOut
, this);
174 Ipc::Forwarder::HandleRemoteAck(const RequestId requestId
)
176 debugs(54, 3, MYNAME
);
177 Must(requestId
!= 0);
179 AsyncCall::Pointer call
= DequeueRequest(requestId
);
181 ScheduleCallHere(call
);