}
void
-Helper::SessionBase::closePipesSafely(const char * const id_name)
+Helper::SessionBase::closePipesSafely()
{
#if _SQUID_WINDOWS_
shutdown(writePipe->fd, SD_BOTH);
if (hIpc) {
if (WaitForSingleObject(hIpc, 5000) != WAIT_OBJECT_0) {
getCurrentTime();
- debugs(84, DBG_IMPORTANT, "WARNING: " << id_name <<
+ debugs(84, DBG_IMPORTANT, "WARNING: " << helper().id_name <<
" #" << index << " (PID " << (long int)pid << ") didn't exit in 5 seconds");
}
CloseHandle(hIpc);
}
-#else
- (void)id_name;
#endif
}
void
-Helper::SessionBase::closeWritePipeSafely(const char * const id_name)
+Helper::SessionBase::closeWritePipeSafely()
{
#if _SQUID_WINDOWS_
shutdown(writePipe->fd, (readPipe->fd == writePipe->fd ? SD_BOTH : SD_SEND));
if (hIpc) {
if (WaitForSingleObject(hIpc, 5000) != WAIT_OBJECT_0) {
getCurrentTime();
- debugs(84, DBG_IMPORTANT, "WARNING: " << id_name <<
+ debugs(84, DBG_IMPORTANT, "WARNING: " << helper().id_name <<
" #" << index << " (PID " << (long int)pid << ") didn't exit in 5 seconds");
}
CloseHandle(hIpc);
}
-#else
- (void)id_name;
#endif
}
void
-Helper::SessionBase::dropQueued(Client &client)
+Helper::SessionBase::dropQueued()
{
while (!requests.empty()) {
// XXX: re-schedule these on another helper?
const auto r = requests.front();
requests.pop_front();
r->reply.result = Helper::Unknown;
- client.callBack(*r);
+ helper().callBack(*r);
delete r;
}
}
}
if (Comm::IsConnOpen(writePipe))
- closeWritePipeSafely(parent->id_name);
+ closeWritePipeSafely();
dlinkDelete(&link, &parent->servers);
}
void
-Helper::Session::dropQueued(Client &client)
+Helper::Session::dropQueued()
{
- SessionBase::dropQueued(client);
+ SessionBase::dropQueued();
requestsIndex.clear();
}
{
/* TODO: walk the local queue of requests and carry them all out */
if (Comm::IsConnOpen(writePipe))
- closeWritePipeSafely(parent->id_name);
+ closeWritePipeSafely();
parent->cancelReservation(reservationId);
if (wfd != rfd)
commSetNonBlocking(wfd);
- AsyncCall::Pointer closeCall = asyncCall(5,4, "Helper::Session::HelperServerClosed", cbdataDialer(Helper::Session::HelperServerClosed, srv));
+ AsyncCall::Pointer closeCall = asyncCall(5, 4, "Helper::Session::HelperServerClosed", cbdataDialer(SessionBase::HelperServerClosed,
+ static_cast<Helper::SessionBase *>(srv)));
+
comm_add_close_handler(rfd, closeCall);
if (hlp->timeout && hlp->childs.concurrency) {
if (wfd != rfd)
commSetNonBlocking(wfd);
- AsyncCall::Pointer closeCall = asyncCall(5,4, "helper_stateful_server::HelperServerClosed", cbdataDialer(helper_stateful_server::HelperServerClosed, srv));
+ AsyncCall::Pointer closeCall = asyncCall(5, 4, "helper_stateful_server::HelperServerClosed", cbdataDialer(Helper::SessionBase::HelperServerClosed,
+ static_cast<Helper::SessionBase *>(srv)));
+
comm_add_close_handler(rfd, closeCall);
AsyncCall::Pointer call = commCbCall(5,4, "helperStatefulHandleRead",
/* the rest of the details is dealt with in the helperServerFree
* close handler
*/
- srv->closePipesSafely(hlp->id_name);
+ srv->closePipesSafely();
}
Assure(!hlp->childs.n_active);
/* the rest of the details is dealt with in the helperStatefulServerFree
* close handler
*/
- srv->closePipesSafely(hlp->id_name);
+ srv->closePipesSafely();
}
}
}
void
-Helper::Session::HelperServerClosed(Session * const srv)
-{
- srv->parent->handleKilledServer(srv);
- srv->dropQueued(*srv->parent);
- delete srv;
-}
-
-// XXX: Essentially duplicates Helper::Session::HelperServerClosed() until we add SessionBase::helper().
-void
-helper_stateful_server::HelperServerClosed(helper_stateful_server *srv)
+Helper::SessionBase::HelperServerClosed(SessionBase * const srv)
{
- srv->parent->handleKilledServer(srv);
- srv->dropQueued(*srv->parent);
+ srv->helper().handleKilledServer(srv);
+ srv->dropQueued();
delete srv;
}
debugs(84, DBG_IMPORTANT, "ERROR: Disconnecting from a " <<
"helper that overflowed " << srv->rbuf_sz << "-byte " <<
"Squid input buffer: " << hlp->id_name << " #" << srv->index);
- srv->closePipesSafely(hlp->id_name);
+ srv->closePipesSafely();
return;
}
if (!srv->flags.shutdown) {
helperKickQueue(hlp);
} else if (!srv->flags.closing && !srv->stats.pending) {
- srv->closeWritePipeSafely(srv->parent->id_name);
+ srv->closeWritePipeSafely();
}
}
debugs(84, 5, "helperHandleRead: " << len << " bytes from " << hlp->id_name << " #" << srv->index);
if (flag != Comm::OK || len == 0) {
- srv->closePipesSafely(hlp->id_name);
+ srv->closePipesSafely();
return;
}
srv->roffset = 0;
srv->rbuf[0] = '\0';
- srv->closePipesSafely(hlp->id_name);
+ srv->closePipesSafely();
return;
}
hlp->id_name << " #" << srv->index);
if (flag != Comm::OK || len == 0) {
- srv->closePipesSafely(hlp->id_name);
+ srv->closePipesSafely();
return;
}
" bytes '" << srv->rbuf << "'");
srv->roffset = 0;
- srv->closePipesSafely(hlp->id_name);
+ srv->closePipesSafely();
return;
}
debugs(84, DBG_IMPORTANT, "ERROR: Disconnecting from a " <<
"helper that overflowed " << srv->rbuf_sz << "-byte " <<
"Squid input buffer: " << hlp->id_name << " #" << srv->index);
- srv->closePipesSafely(hlp->id_name);
+ srv->closePipesSafely();
return;
}
/**
if (!srv->flags.shutdown) {
helperStatefulKickQueue(srv->parent);
} else if (!srv->flags.closing && !srv->reserved() && !srv->stats.pending) {
- srv->closeWritePipeSafely(srv->parent->id_name);
+ srv->closeWritePipeSafely();
return;
}
}
public:
~SessionBase() override;
+ /// close handler to handle exited server processes
+ static void HelperServerClosed(SessionBase *);
+
/** Closes pipes to the helper safely.
* Handles the case where the read and write pipes are the same FD.
- *
- * \param name displayed for the helper being shutdown if logging an error
*/
- void closePipesSafely(const char *name);
+ void closePipesSafely();
/** Closes the reading pipe.
* If the read and write sockets are the same the write pipe will
* also be closed. Otherwise its left open for later handling.
- *
- * \param name displayed for the helper being shutdown if logging an error
*/
- void closeWritePipeSafely(const char *name);
+ void closeWritePipeSafely();
// TODO: Teach each child to report its child-specific state instead.
/// whether the server is locked for exclusive use by a client
virtual bool reserved() = 0;
+ /// our creator (parent) object
+ virtual Client &helper() const = 0;
+
/// dequeues and sends an Unknown answer to all queued requests
- virtual void dropQueued(Client &);
+ virtual void dropQueued();
public:
/// Helper program identifier; does not change when contents do,
/* SessionBase API */
bool reserved() override {return false;}
- void dropQueued(Client &) override;
+ void dropQueued() override;
+ Client &helper() const override { return *parent; }
/// Read timeout handler
static void requestTimeout(const CommTimeoutCbParams &io);
-
- /// close handler to handle exited server processes
- static void HelperServerClosed(Session *);
};
} // namespace Helper
void reserve();
void clearReservation();
- /* HelperServerBase API */
+ /* Helper::SessionBase API */
bool reserved() override {return reservationId.reserved();}
-
- /// close handler to handle exited server processes
- static void HelperServerClosed(helper_stateful_server *srv);
+ Helper::Client &helper() const override { return *parent; }
statefulhelper::Pointer parent;