Author: toad
Date: 2006-06-21 16:48:37 +0000 (Wed, 21 Jun 2006)
New Revision: 9337
Modified:
trunk/freenet/src/freenet/io/comm/UdpSocketManager.java
trunk/freenet/src/freenet/node/Node.java
trunk/freenet/src/freenet/node/Version.java
Log:
832: Auto-restart the node if the UdpSocketManager (packet receiver thread)
hangs.
Modified: trunk/freenet/src/freenet/io/comm/UdpSocketManager.java
===================================================================
--- trunk/freenet/src/freenet/io/comm/UdpSocketManager.java 2006-06-21
16:27:27 UTC (rev 9336)
+++ trunk/freenet/src/freenet/io/comm/UdpSocketManager.java 2006-06-21
16:48:37 UTC (rev 9337)
@@ -22,6 +22,9 @@
import java.net.*;
import java.util.*;
+import org.tanukisoftware.wrapper.WrapperManager;
+
+import freenet.node.Node;
import freenet.node.PeerNode;
import freenet.support.Logger;
@@ -44,11 +47,17 @@
private boolean _isDone = false;
private static UdpSocketManager _usm;
private static final int MAX_UNMATCHED_FIFO_SIZE = 50000;
+ private volatile int lastTimeInSeconds;
- protected UdpSocketManager() {
+ // Icky layer violation, but we need to know the Node to work around
the EvilJVMBug.
+ private final Node node;
+
+ protected UdpSocketManager(Node node) {
+ this.node = node;
}
public void start() {
+ lastTimeInSeconds = (int) (System.currentTimeMillis() / 1000);
setDaemon(true);
setPriority(Thread.MAX_PRIORITY);
super.start();
@@ -66,9 +75,39 @@
} catch (InterruptedException e) {
// Ignore
}
- if(UdpSocketManager.this.isAlive())
+ if(UdpSocketManager.this.isAlive()) {
Logger.minor(this, "PING on
"+UdpSocketManager.this);
- else {
+ long time = System.currentTimeMillis();
+ int timeSecs = (int) (time / 1000);
+ if(timeSecs - lastTimeInSeconds > 3*60)
{
+
+ // USM has hung.
+ // Probably caused by the
EvilJVMBug (see PacketSender).
+ // We'd better restart... :(
+
+
if(!Node.logConfigHandler.getFileLoggerHook().hasRedirectedStdOutErrNoLock())
+
System.err.println("Restarting node: UdpSocketManager froze for 3 minutes!");
+
+ try {
+
if(node.isUsingWrapper()){
+
WrapperManager.requestThreadDump();
+
WrapperManager.restart();
+ }else{
+
if(!Node.logConfigHandler.getFileLoggerHook().hasRedirectedStdOutErrNoLock())
+
System.err.println("Exiting on deadlock, but not running in the wrapper! Please
restart the node manually.");
+
+ // No wrapper :
we don't want to let it harm the network!
+ node.exit();
+ }
+ } catch (Throwable t) {
+
if(!Node.logConfigHandler.getFileLoggerHook().hasRedirectedStdOutErrNoLock()) {
+
System.err.println("Error : can't restart the node : consider installing the
wrapper. PLEASE REPORT THAT ERROR TO devl at freenetproject.org");
+
t.printStackTrace();
+ }
+ node.exit();
+ }
+ }
+ } else {
Logger.error(this, "MAIN LOOP
TERMINATED");
System.err.println("MAIN LOOP
TERMINATED!");
System.exit(freenet.node.Node.EXIT_MAIN_LOOP_LOST);
@@ -77,8 +116,9 @@
}
}
- public UdpSocketManager(int listenPort, InetAddress bindto) throws
SocketException {
+ public UdpSocketManager(int listenPort, InetAddress bindto, Node node)
throws SocketException {
super("UdpSocketManager sender thread on port " + listenPort);
+ this.node = node;
// Keep the Updater code in, just commented out, for now
// We may want to be able to do on-line updates.
// if (Updater.hasResource()) {
@@ -133,6 +173,7 @@
private void runLoop() {
while (/*_active*/true) {
try {
+ lastTimeInSeconds = (int)
(System.currentTimeMillis() / 1000);
realRun();
} catch (Throwable t) {
Logger.error(this, "Caught " + t, t);
@@ -543,12 +584,12 @@
return _usm;
}
- public static void init(int externalListenPort, InetAddress bindto)
- throws SocketException
- {
- _usm = new UdpSocketManager(externalListenPort, bindto);
- }
-
+// public static void init(int externalListenPort, InetAddress bindto)
+// throws SocketException
+// {
+// _usm = new UdpSocketManager(externalListenPort, bindto);
+// }
+//
public int getPortNumber() {
return _sock.getLocalPort();
}
Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java 2006-06-21 16:27:27 UTC (rev
9336)
+++ trunk/freenet/src/freenet/node/Node.java 2006-06-21 16:48:37 UTC (rev
9337)
@@ -369,7 +369,7 @@
/** Maximum size of gzipped logfiles */
static long maxLogSize;
/** Log config handler */
- static LoggingConfigHandler logConfigHandler;
+ public static LoggingConfigHandler logConfigHandler;
/** If true, local requests and inserts aren't cached.
* This opens up a glaring vulnerability; connected nodes
@@ -1084,7 +1084,7 @@
for(int i=0;i<200000;i++) {
int portNo = 1024 + random.nextInt(65535-1024);
try {
- u = new UdpSocketManager(portNo,
InetAddress.getByName(bindto));
+ u = new UdpSocketManager(portNo,
InetAddress.getByName(bindto), this);
port = u.getPortNumber();
break;
} catch (Exception e) {
@@ -1098,7 +1098,7 @@
throw new
NodeInitException(EXIT_NO_AVAILABLE_UDP_PORTS, "Could not find an available UDP
port number for FNP (none specified)");
} else {
try {
- u = new UdpSocketManager(port,
InetAddress.getByName(bindto));
+ u = new UdpSocketManager(port,
InetAddress.getByName(bindto), this);
} catch (Exception e) {
throw new
NodeInitException(EXIT_IMPOSSIBLE_USM_PORT, "Could not bind to port: "+port+"
(node already running?)");
}
Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2006-06-21 16:27:27 UTC (rev
9336)
+++ trunk/freenet/src/freenet/node/Version.java 2006-06-21 16:48:37 UTC (rev
9337)
@@ -18,7 +18,7 @@
public static final String protocolVersion = "1.0";
/** The build number of the current revision */
- private static final int buildNumber = 831;
+ private static final int buildNumber = 832;
/** Oldest build of Fred we will talk to */
private static final int lastGoodBuild = 765;