return runners.size();
}
+int
+DeregisterRunner(RegisteredRunner *rr)
+{
+ Runners &runners = GetRunners();
+ runners.erase(rr);
+ return runners.size();
+}
+
void
RunRegistered(const RegisteredRunner::Method &m)
{
/// Meant for cleanup and state saving that may require other modules.
virtual void startShutdown() {}
+ /// Called after shutdown_lifetime grace period ends and before stopping
+ /// the main loop. At least one main loop iteration is guaranteed after
+ /// this call.
+ /// Meant for cleanup and state saving that may require other modules.
+ virtual void endingShutdown() {}
+
/// Called after stopping the main loop and before releasing memory.
/// Meant for quick/basic cleanup that does not require any other modules.
virtual ~RegisteredRunner() {}
/// registers a given runner with the given registry and returns registry count
int RegisterRunner(RegisteredRunner *rr);
+/// de-registers a given runner with the given registry and returns registry count
+int DeregisterRunner(RegisteredRunner *rr);
+
/// Calls a given method of all runners.
/// All runners are destroyed after the finishShutdown() call.
void RunRegistered(const RegisteredRunner::Method &m);
{
debugs(33, 2, HERE << clientConnection);
flags.readMore = false;
+ DeregisterRunner(this);
clientdbEstablished(clientConnection->remote, -1); /* decrement */
assert(areAllContextsForThisConnection());
freeAllContexts();
return context;
}
+void
+ConnStateData::startShutdown()
+{
+ // RegisteredRunner API callback - Squid has been shut down
+
+ // if connection is idle terminate it now,
+ // otherwise wait for grace period to end
+ if (getConcurrentRequestCount() == 0)
+ endingShutdown();
+}
+
+void
+ConnStateData::endingShutdown()
+{
+ // RegisteredRunner API callback - Squid shutdown grace period is over
+
+ // force the client connection to close immediately
+ // swanSong() in the close handler will cleanup.
+ if (Comm::IsConnOpen(clientConnection))
+ clientConnection->close();
+
+ // deregister now to ensure finalShutdown() does not kill us prematurely.
+ // fd_table purge will cleanup if close handler was not fast enough.
+ DeregisterRunner(this);
+}
+
char *
skipLeadingSpace(char *aString)
{
transferProtocol = port->transport; // default to the *_port protocol= setting. may change later.
log_addr = xact->tcpClient->remote;
log_addr.applyMask(Config.Addrs.client_netmask);
+
+ // register to receive notice of Squid signal events
+ // which may affect long persisting client connections
+ RegisterRunner(this);
}
void
#ifndef SQUID_CLIENTSIDE_H
#define SQUID_CLIENTSIDE_H
+#include "base/RunnersRegistry.h"
#include "clientStreamForward.h"
#include "comm.h"
#include "helper/forward.h"
*
* If the above can be confirmed accurate we can call this object PipelineManager or similar
*/
-class ConnStateData : public BodyProducer, public HttpControlMsgSink
+class ConnStateData : public BodyProducer, public HttpControlMsgSink, public RegisteredRunner
{
public:
/// client data which may need to forward as-is to server after an
/// on_unsupported_protocol tunnel decision.
SBuf preservedClientData;
+
+ /* Registered Runner API */
+ virtual void startShutdown();
+ virtual void endingShutdown();
+
protected:
void startDechunkingRequest();
void finishDechunkingRequest(bool withSuccess);
EventLoop::Running->stop();
}
+ static void FinalShutdownRunners(void *) {
+ RunRegisteredHere(RegisteredRunner::endingShutdown);
+
+ // XXX: this should be a Runner.
+#if USE_AUTH
+ /* detach the auth components (only do this on full shutdown) */
+ Auth::Scheme::FreeAll();
+#endif
+
+ eventAdd("SquidTerminate", &StopEventLoop, NULL, 0, 1, false);
+ }
+
void doShutdown(time_t wait);
void handleStoppedChild();
/* run the closure code which can be shared with reconfigure */
serverConnectionsClose();
-#if USE_AUTH
- /* detach the auth components (only do this on full shutdown) */
- Auth::Scheme::FreeAll();
-#endif
RunRegisteredHere(RegisteredRunner::startShutdown);
}
WIN32_svcstatusupdate(SERVICE_STOP_PENDING, (wait + 1) * 1000);
#endif
- eventAdd("SquidShutdown", &StopEventLoop, this, (double) (wait + 1), 1, false);
+ eventAdd("SquidShutdown", &FinalShutdownRunners, this, (double) (wait + 1), 1, false);
}
void