=== modified file 'src/auth/Scheme.cc'
--- src/auth/Scheme.cc	2013-10-25 00:13:46 +0000
+++ src/auth/Scheme.cc	2014-01-13 01:09:50 +0000
@@ -35,6 +35,7 @@
 #include "auth/Config.h"
 #include "auth/Gadgets.h"
 #include "auth/Scheme.h"
+#include "base/RunnersRegistry.h"
 #include "globals.h"
 
 Vector<Auth::Scheme::Pointer> *Auth::Scheme::_Schemes = NULL;
@@ -90,3 +91,11 @@
         scheme->shutdownCleanup();
     }
 }
+
+class AuthShutdownRr : public RegisteredRunner
+{
+public:
+    // XXX: make this depend on the server ports being closed and no client connections open
+    virtual void run(const RunnerRegistry &) {Auth::Scheme::FreeAll();}
+};
+RunnerRegistrationEntry(rrShutdown, AuthShutdownRr);

=== modified file 'src/base/RunnersRegistry.h'
--- src/base/RunnersRegistry.h	2012-08-28 13:00:30 +0000
+++ src/base/RunnersRegistry.h	2014-01-12 22:38:29 +0000
@@ -37,6 +37,10 @@
     /// modules and features based on the finalized configuration.
     rrAfterConfig,
 
+    /// Managed by main.cc. Activated after receiving the shutdown signal
+    /// and deactivated before exit()-ing.
+    rrShutdown,
+
     rrEnd ///< not a real registry, just a label to mark the end of enum
 } RunnerRegistry;
 

=== modified file 'src/main.cc'
--- src/main.cc	2014-01-12 17:51:12 +0000
+++ src/main.cc	2014-01-14 23:14:31 +0000
@@ -259,24 +259,27 @@
 void
 SignalEngine::doShutdown(time_t wait)
 {
+    shutting_down = 1;
+
     debugs(1, DBG_IMPORTANT, "Preparing for shutdown after " << statCounter.client_http.requests << " requests");
     debugs(1, DBG_IMPORTANT, "Waiting " << wait << " seconds for active connections to finish");
 
-    shutting_down = 1;
-
+    eventAdd("SquidShutdown", &StopEventLoop, this, (double) (wait + 1), 1, false);
 #if USE_WIN32_SERVICE
     WIN32_svcstatusupdate(SERVICE_STOP_PENDING, (wait + 1) * 1000);
 #endif
 
-    /* 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
-    eventAdd("SquidShutdown", &StopEventLoop, this, (double) (wait + 1), 1, false);
+    ActivateRegistered(rrShutdown);
 }
 
+/// close the server listening ports when shutting down
+class ServerPortsShutdownRr : public RegisteredRunner
+{
+public:
+    virtual void run(const RunnerRegistry &) {serverConnectionsClose();}
+};
+RunnerRegistrationEntry(rrShutdown, ServerPortsShutdownRr);
+
 static void
 usage(void)
 {
@@ -1809,6 +1812,7 @@
             DeactivateRegistered(rrAfterConfig);
             DeactivateRegistered(rrClaimMemoryNeeds);
             DeactivateRegistered(rrFinalizeConfig);
+            DeactivateRegistered(rrShutdown);
             enter_suid();
 
             if (TheKids.someSignaled(SIGINT) || TheKids.someSignaled(SIGTERM)) {
@@ -1907,6 +1911,8 @@
     DeactivateRegistered(rrAfterConfig);
     DeactivateRegistered(rrClaimMemoryNeeds);
     DeactivateRegistered(rrFinalizeConfig);
+    DeactivateRegistered(rrShutdown);
+
 #if LEAK_CHECK_MODE && 0 /* doesn't work at the moment */
 
     configFreeMemory();


