From 3455d3f9433be51a7b4fa89a2ca6759c7878fe11 Mon Sep 17 00:00:00 2001 From: zzz Date: Sun, 10 Jul 2011 15:04:42 +0000 Subject: [PATCH] * Message Registry: Clear pending messages at restart / shutdown * OCMOSJ: Clear caches at restart * UPnP: - Fix device rediscovery and port opening after restart --- history.txt | 17 +++++++++++ .../src/net/i2p/router/ClientMessagePool.java | 7 +++++ .../src/net/i2p/router/InNetMessagePool.java | 5 ++++ router/java/src/net/i2p/router/Router.java | 4 ++- .../src/net/i2p/router/RouterVersion.java | 2 +- .../transport/OutboundMessageRegistry.java | 30 ++++++++++++++++--- .../src/net/i2p/router/transport/UPnP.java | 16 +++++++++- .../net/i2p/router/transport/UPnPManager.java | 4 ++- .../org/cybergarage/upnp/ControlPoint.java | 6 ++++ 9 files changed, 83 insertions(+), 8 deletions(-) diff --git a/history.txt b/history.txt index bee10d1a8a..b2758a1fbe 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,20 @@ +2011-07-10 zzz + * DH, YK: + - Improve YK speed test + - Shut down thread faster + - Refiller keeps going until full + - Cleanups + * I2PTunnel: Fix a shutdown hang + * Message Registry: Clear pending messages at restart / shutdown + * OCMOSJ: Clear caches at restart + * Router Clock: First cut at recognizing and reacting to large system + clock shifts by partially restarting the router. Also improve + restarts initiated from config.jsp + Tickets #465, #468, #494 + * UPnP: + - Wait for a while to ensure port removal at shutdown or restart + - Fix device rediscovery and port opening after restart + 2011-07-08 zzz * Findbugs: Several fixes and cleanups * I2NP: Consolidate common code from TunnelBuildMessage and diff --git a/router/java/src/net/i2p/router/ClientMessagePool.java b/router/java/src/net/i2p/router/ClientMessagePool.java index 9a8c314da3..faa4149ed5 100644 --- a/router/java/src/net/i2p/router/ClientMessagePool.java +++ b/router/java/src/net/i2p/router/ClientMessagePool.java @@ -39,6 +39,13 @@ public class ClientMessagePool { OutboundClientMessageOneShotJob.clearAllCaches(); } + /** + * @since 0.8.8 + */ + public void restart() { + shutdown(); + } + /** * Add a new message to the pool. The message can either be locally or * remotely destined. diff --git a/router/java/src/net/i2p/router/InNetMessagePool.java b/router/java/src/net/i2p/router/InNetMessagePool.java index d6067b2b36..a6fdbae3a3 100644 --- a/router/java/src/net/i2p/router/InNetMessagePool.java +++ b/router/java/src/net/i2p/router/InNetMessagePool.java @@ -321,11 +321,15 @@ public class InNetMessagePool implements Service { } public void renderStatusHTML(Writer out) {} + + /** does nothing since we aren't threaded */ public void restart() { shutdown(); try { Thread.sleep(100); } catch (InterruptedException ie) {} startup(); } + + /** does nothing since we aren't threaded */ public void shutdown() { _alive = false; if (!DISPATCH_DIRECT) { @@ -337,6 +341,7 @@ public class InNetMessagePool implements Service { } } + /** does nothing since we aren't threaded */ public void startup() { _alive = true; _dispatchThreaded = DEFAULT_DISPATCH_THREADED; diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java index 194cd1b3db..23990673c7 100644 --- a/router/java/src/net/i2p/router/Router.java +++ b/router/java/src/net/i2p/router/Router.java @@ -1258,6 +1258,7 @@ public class Router implements RouterClock.ClockShiftListener { _log.logAlways(Log.WARN, "Stopping the client manager"); try { _context.clientManager().shutdown(); } catch (Throwable t) { _log.log(Log.CRIT, "Error stopping the client manager", t); } _log.logAlways(Log.WARN, "Stopping the comm system"); + try { _context.messageRegistry().restart(); } catch (Throwable t) { _log.log(Log.CRIT, "Error restarting the message registry", t); } try { _context.commSystem().restart(); } catch (Throwable t) { _log.log(Log.CRIT, "Error restarting the comm system", t); } _log.logAlways(Log.WARN, "Stopping the tunnel manager"); try { _context.tunnelManager().restart(); } catch (Throwable t) { _log.log(Log.CRIT, "Error restarting the tunnel manager", t); } @@ -1272,7 +1273,8 @@ public class Router implements RouterClock.ClockShiftListener { _log.logAlways(Log.WARN, "Restarting the comm system"); _log.logAlways(Log.WARN, "Restarting the tunnel manager"); _log.logAlways(Log.WARN, "Restarting the client manager"); - try { _context.clientManager().startup(); } catch (Throwable t) { _log.log(Log.CRIT, "Error stopping the client manager", t); } + try { _context.clientMessagePool().restart(); } catch (Throwable t) { _log.log(Log.CRIT, "Error restarting the CMP", t); } + try { _context.clientManager().startup(); } catch (Throwable t) { _log.log(Log.CRIT, "Error starting the client manager", t); } _isAlive = true; rebuildRouterInfo(); diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index a6204817e3..f2522cd4ed 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 8; + public final static long BUILD = 9; /** for example "-test" */ public final static String EXTRA = ""; diff --git a/router/java/src/net/i2p/router/transport/OutboundMessageRegistry.java b/router/java/src/net/i2p/router/transport/OutboundMessageRegistry.java index b8261d1d2b..8d79f1c0ff 100644 --- a/router/java/src/net/i2p/router/transport/OutboundMessageRegistry.java +++ b/router/java/src/net/i2p/router/transport/OutboundMessageRegistry.java @@ -28,15 +28,15 @@ import net.i2p.util.Log; import net.i2p.util.SimpleTimer; public class OutboundMessageRegistry { - private Log _log; + private final Log _log; /** list of currently active MessageSelector instances */ private final List _selectors; /** map of active MessageSelector to either an OutNetMessage or a List of OutNetMessages causing it (for quick removal) */ private final Map _selectorToMessage; /** set of active OutNetMessage (for quick removal and selector fetching) */ private final Set _activeMessages; - private CleanupTask _cleanupTask; - private RouterContext _context; + private final CleanupTask _cleanupTask; + private final RouterContext _context; public OutboundMessageRegistry(RouterContext context) { _context = context; @@ -47,7 +47,29 @@ public class OutboundMessageRegistry { _cleanupTask = new CleanupTask(); } - public void shutdown() {} + /** + * Does something @since 0.8.8 + */ + public void shutdown() { + synchronized (_selectors) { + _selectors.clear(); + } + synchronized (_selectorToMessage) { + _selectorToMessage.clear(); + } + // Calling the fail job for every active message would + // be way too much at shutdown/restart, right? + synchronized (_activeMessages) { + _activeMessages.clear(); + } + } + + /** + * @since 0.8.8 + */ + public void restart() { + shutdown(); + } /** * Retrieve all messages that are waiting for the specified message. In diff --git a/router/java/src/net/i2p/router/transport/UPnP.java b/router/java/src/net/i2p/router/transport/UPnP.java index 862f12cbb7..8da739e831 100644 --- a/router/java/src/net/i2p/router/transport/UPnP.java +++ b/router/java/src/net/i2p/router/transport/UPnP.java @@ -88,6 +88,9 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener { } public boolean runPlugin() { + synchronized(lock) { + portsToForward = null; + } return super.start(); } @@ -95,6 +98,9 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener { * WARNING - Blocking up to 2 seconds */ public void terminate() { + synchronized(lock) { + portsToForward = null; + } // this gets spun off in a thread... unregisterPortMappings(); // If we stop too early and we've forwarded multiple ports, @@ -621,7 +627,11 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener { } portsToForward = ports; } - if(_router == null) return; // When one is found, we will do the forwards + if(_router == null) { + if (_log.shouldLog(Log.WARN)) + _log.warn("No UPnP router available to update"); + return; // When one is found, we will do the forwards + } } if(portsToDumpNow != null) unregisterPorts(portsToDumpNow); @@ -645,6 +655,8 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener { * so throw this in a thread. */ private void registerPorts(Set portsToForwardNow) { + if (_log.shouldLog(Log.INFO)) + _log.info("Starting thread to forward " + portsToForwardNow.size() + " ports"); Thread t = new Thread(new RegisterPortsThread(portsToForwardNow)); t.setName("UPnP Port Opener " + (++__id)); t.setDaemon(true); @@ -683,6 +695,8 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener { * so throw this in a thread. */ private void unregisterPorts(Set portsToForwardNow) { + if (_log.shouldLog(Log.INFO)) + _log.info("Starting thread to un-forward " + portsToForwardNow.size() + " ports"); Thread t = new Thread(new UnregisterPortsThread(portsToForwardNow)); t.setName("UPnP Port Closer " + (++__id)); t.setDaemon(true); diff --git a/router/java/src/net/i2p/router/transport/UPnPManager.java b/router/java/src/net/i2p/router/transport/UPnPManager.java index 40829c1e5b..1bf1f5975f 100644 --- a/router/java/src/net/i2p/router/transport/UPnPManager.java +++ b/router/java/src/net/i2p/router/transport/UPnPManager.java @@ -60,6 +60,8 @@ class UPnPManager { } public synchronized void start() { + if (_log.shouldLog(Log.DEBUG)) + _log.debug("UPnP Start"); if (!_isRunning) _isRunning = _upnp.runPlugin(); if (!_isRunning) @@ -83,7 +85,7 @@ class UPnPManager { */ public void update(Map ports) { if (_log.shouldLog(Log.DEBUG)) - _log.debug("UPnP Update:"); + _log.debug("UPnP Update with " + ports.size() + " ports"); if (!_isRunning) return; Set forwards = new HashSet(ports.size()); diff --git a/router/java/src/org/cybergarage/upnp/ControlPoint.java b/router/java/src/org/cybergarage/upnp/ControlPoint.java index b2def64082..781786160a 100644 --- a/router/java/src/org/cybergarage/upnp/ControlPoint.java +++ b/router/java/src/org/cybergarage/upnp/ControlPoint.java @@ -914,6 +914,12 @@ public class ControlPoint implements HTTPRequestListener setRenewSubscriber(null); } + // I2P so we will re-notify on restart + DeviceList dl = getDeviceList(); + for (int i = 0; i < dl.size(); i++) { + removeDevice(dl.getDevice(i)); + } + return true; }