Author: robert
Date: 2008-02-11 19:23:18 +0000 (Mon, 11 Feb 2008)
New Revision: 17783
Modified:
trunk/freenet/src/freenet/node/NodeDispatcher.java
Log:
cleanup old routing contexts (i.e. memory leak)
Modified: trunk/freenet/src/freenet/node/NodeDispatcher.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeDispatcher.java 2008-02-11 18:30:34 UTC
(rev 17782)
+++ trunk/freenet/src/freenet/node/NodeDispatcher.java 2008-02-11 19:23:18 UTC
(rev 17783)
@@ -5,6 +5,7 @@
import java.util.HashSet;
import java.util.Hashtable;
+import java.util.Iterator;
import freenet.crypt.HMAC;
import freenet.crypt.SHA256;
@@ -35,16 +36,20 @@
*
* Probably a few others; those are the important bits.
*/
-public class NodeDispatcher implements Dispatcher {
+public class NodeDispatcher implements Dispatcher, Runnable {
private static boolean logMINOR;
final Node node;
private NodeStats nodeStats;
+
+ private static final long STALE_CONTEXT=20000;
+ private static final long STALE_CONTEXT_CHECK=20000;
NodeDispatcher(Node node) {
this.node = node;
this.nodeStats = node.nodeStats;
logMINOR = Logger.shouldLog(Logger.MINOR, this);
+ node.getTicker().queueTimedJob(this, STALE_CONTEXT_CHECK);
}
public boolean handleMessage(Message m) {
@@ -451,7 +456,6 @@
}
}
- //FIXME: PLEASE! When are these contexts ever cleaned up!!!
Memory-leak-per-ping!
final Hashtable routedContexts = new Hashtable();
static class RoutedContext {
@@ -476,6 +480,23 @@
routedTo.add(n);
}
}
+
+ /**
+ * Cleanup any old/stale routing contexts and reschedule execution.
+ */
+ public void run() {
+ long now=System.currentTimeMillis();
+ synchronized (routedContexts) {
+ Iterator i=routedContexts.values().iterator();
+ while (i.hasNext()) {
+ RoutedContext rc = (RoutedContext)i.next();
+ if (now-rc.createdTime > STALE_CONTEXT) {
+ i.remove();
+ }
+ }
+ }
+ node.getTicker().queueTimedJob(this, STALE_CONTEXT_CHECK);
+ }
/**
* Handle an FNPRoutedRejected message.
@@ -525,7 +546,9 @@
return true;
}
ctx = new RoutedContext(m, source);
- routedContexts.put(lid, ctx);
+ synchronized (routedContexts) {
+ routedContexts.put(lid, ctx);
+ }
// source == null => originated locally, keep full htl
double target = m.getDouble(DMT.TARGET_LOCATION);
if(logMINOR) Logger.minor(this, "id "+id+" from "+source+" htl
"+htl+" target "+target);