From 7a684c160b50988cb9103d6a0033af64eb18bd08 Mon Sep 17 00:00:00 2001
From: zzz <zzz@mail.i2p>
Date: Tue, 24 Feb 2009 23:15:26 +0000
Subject: [PATCH]     * Routerconsole:       - Thread hard shutdown and restart
 requests from the routerconsole,         and add a delay even if no tunnels,
 to allow time for a UI response

---
 .../net/i2p/router/web/ConfigRestartBean.java | 19 +++++++++---
 router/java/src/net/i2p/router/Router.java    | 30 +++++++++++++++----
 2 files changed, 39 insertions(+), 10 deletions(-)

diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigRestartBean.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigRestartBean.java
index 3c9fe1bbf4..75a8108c50 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigRestartBean.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigRestartBean.java
@@ -26,12 +26,14 @@ public class ConfigRestartBean {
         if ( (nonce != null) && (systemNonce.equals(nonce)) && (action != null) ) {
             if ("shutdownImmediate".equals(action)) {
                 ctx.router().addShutdownTask(new ConfigServiceHandler.UpdateWrapperManagerTask(Router.EXIT_HARD));
-                ctx.router().shutdown(Router.EXIT_HARD); // never returns
+                //ctx.router().shutdown(Router.EXIT_HARD); // never returns
+                ctx.router().shutdownGracefully(Router.EXIT_HARD); // give the UI time to respond
             } else if ("cancelShutdown".equals(action)) {
                 ctx.router().cancelGracefulShutdown();
             } else if ("restartImmediate".equals(action)) {
                 ctx.router().addShutdownTask(new ConfigServiceHandler.UpdateWrapperManagerTask(Router.EXIT_HARD_RESTART));
-                ctx.router().shutdown(Router.EXIT_HARD_RESTART); // never returns
+                //ctx.router().shutdown(Router.EXIT_HARD_RESTART); // never returns
+                ctx.router().shutdownGracefully(Router.EXIT_HARD_RESTART); // give the UI time to respond
             } else if ("restart".equals(action)) {
                 ctx.router().addShutdownTask(new ConfigServiceHandler.UpdateWrapperManagerTask(Router.EXIT_GRACEFUL_RESTART));
                 ctx.router().shutdownGracefully(Router.EXIT_GRACEFUL_RESTART);
@@ -79,9 +81,18 @@ public class ConfigRestartBean {
     }
 
     private static boolean isShuttingDown(RouterContext ctx) {
-        return Router.EXIT_GRACEFUL == ctx.router().scheduledGracefulExitCode();
+        return Router.EXIT_GRACEFUL == ctx.router().scheduledGracefulExitCode() ||
+               Router.EXIT_HARD == ctx.router().scheduledGracefulExitCode();
     }
     private static boolean isRestarting(RouterContext ctx) {
-        return Router.EXIT_GRACEFUL_RESTART == ctx.router().scheduledGracefulExitCode();
+        return Router.EXIT_GRACEFUL_RESTART == ctx.router().scheduledGracefulExitCode() ||
+               Router.EXIT_HARD_RESTART == ctx.router().scheduledGracefulExitCode();
+    }
+    /** this is for summaryframe.jsp */
+    public static long getRestartTimeRemaining() {
+        RouterContext ctx = ContextHelper.getContext(null);
+        if (ctx.router().gracefulShutdownInProgress())
+            return ctx.router().getShutdownTimeRemaining();
+        return Long.MAX_VALUE/2;  // summaryframe.jsp adds a safety factor so we don't want to overflow...
     }
 }
diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java
index 033678924c..77e4b19681 100644
--- a/router/java/src/net/i2p/router/Router.java
+++ b/router/java/src/net/i2p/router/Router.java
@@ -446,13 +446,14 @@ public class Router {
      */
     private static final String _rebuildFiles[] = new String[] { "router.info", 
                                                                  "router.keys",
-                                                                 "netDb/my.info",
-                                                                 "connectionTag.keys",
+                                                                 "netDb/my.info",      // no longer used
+                                                                 "connectionTag.keys", // never used?
                                                                  "keyBackup/privateEncryption.key",
                                                                  "keyBackup/privateSigning.key",
                                                                  "keyBackup/publicEncryption.key",
                                                                  "keyBackup/publicSigning.key",
-                                                                 "sessionKeys.dat" };
+                                                                 "sessionKeys.dat"     // no longer used
+                                                               };
 
     static final String IDENTLOG = "identlog.txt";
     public static void killKeys() {
@@ -859,6 +860,10 @@ public class Router {
     public void shutdownGracefully() {
         shutdownGracefully(EXIT_GRACEFUL);
     }
+    /**
+     * Call this with EXIT_HARD or EXIT_HARD_RESTART for a non-blocking,
+     * hard, non-graceful shutdown with a brief delay to allow a UI response
+     */
     public void shutdownGracefully(int exitCode) {
         _gracefulExitCode = exitCode;
         _config.setProperty(PROP_SHUTDOWN_IN_PROGRESS, "true");
@@ -887,7 +892,9 @@ public class Router {
     }
     /** How long until the graceful shutdown will kill us?  */
     public long getShutdownTimeRemaining() {
-        if (_gracefulExitCode <= 0) return -1;
+        if (_gracefulExitCode <= 0) return -1; // maybe Long.MAX_VALUE would be better?
+        if (_gracefulExitCode == EXIT_HARD || _gracefulExitCode == EXIT_HARD_RESTART)
+            return 0;
         long exp = _context.tunnelManager().getLastParticipatingExpiration();
         if (exp < 0)
             return -1;
@@ -906,9 +913,20 @@ public class Router {
             while (true) {
                 boolean shutdown = (null != _config.getProperty(PROP_SHUTDOWN_IN_PROGRESS));
                 if (shutdown) {
-                    if (_context.tunnelManager().getParticipatingCount() <= 0) {
-                        if (_log.shouldLog(Log.CRIT))
+                    if (_gracefulExitCode == EXIT_HARD || _gracefulExitCode == EXIT_HARD_RESTART ||
+                        _context.tunnelManager().getParticipatingCount() <= 0) {
+                        if (_gracefulExitCode == EXIT_HARD)
+                            _log.log(Log.CRIT, "Shutting down after a brief delay");
+                        else if (_gracefulExitCode == EXIT_HARD_RESTART)
+                            _log.log(Log.CRIT, "Restarting after a brief delay");
+                        else
                             _log.log(Log.CRIT, "Graceful shutdown progress - no more tunnels, safe to die");
+                        // Allow time for a UI reponse
+                        try {
+                            synchronized (Thread.currentThread()) {
+                                Thread.currentThread().wait(2*1000);
+                            }
+                        } catch (InterruptedException ie) {}
                         shutdown(_gracefulExitCode);
                         return;
                     } else {
-- 
GitLab