diff --git a/apps/BOB/src/net/i2p/BOB/BOB.java b/apps/BOB/src/net/i2p/BOB/BOB.java index 48a0e067c6..d2c0ef810d 100644 --- a/apps/BOB/src/net/i2p/BOB/BOB.java +++ b/apps/BOB/src/net/i2p/BOB/BOB.java @@ -34,6 +34,8 @@ import java.util.Properties; import net.i2p.client.I2PClient; import net.i2p.client.streaming.RetransmissionTimer; import net.i2p.util.Log; +import net.i2p.util.SimpleScheduler; +import net.i2p.util.SimpleTimer2; /** * @@ -159,9 +161,10 @@ public class BOB { // Set up all defaults to be passed forward to other threads. // Re-reading the config file in each thread is pretty damn stupid. String configLocation = System.getProperty(PROP_CONFIG_LOCATION, "bob.config"); - // This is here just to ensure there is no interference with our threadgroups. RetransmissionTimer Y = RetransmissionTimer.getInstance(); + SimpleScheduler Y1 = SimpleScheduler.getInstance(); + SimpleTimer2 Y2 = SimpleTimer2.getInstance(); i = Y.hashCode(); { diff --git a/apps/BOB/src/net/i2p/BOB/Main.java b/apps/BOB/src/net/i2p/BOB/Main.java index b32e4758ef..aa56e83e02 100644 --- a/apps/BOB/src/net/i2p/BOB/Main.java +++ b/apps/BOB/src/net/i2p/BOB/Main.java @@ -25,6 +25,7 @@ package net.i2p.BOB; import net.i2p.client.streaming.RetransmissionTimer; import net.i2p.util.SimpleScheduler; +import net.i2p.util.SimpleTimer2; /** * Start from command line * @@ -39,10 +40,13 @@ public class Main { public static void main(String[] args) { // THINK THINK THINK THINK THINK THINK RetransmissionTimer Y = RetransmissionTimer.getInstance(); - // needs SimpleScheduler - // no way to stop the scheduler?!? - SimpleScheduler.getInstance(); + SimpleScheduler Y1 = SimpleScheduler.getInstance(); + SimpleTimer2 Y2 = SimpleTimer2.getInstance(); + BOB.main(args); + + Y2.stop(); + Y1.stop(); Y.stop(); } } diff --git a/core/java/src/net/i2p/util/SimpleScheduler.java b/core/java/src/net/i2p/util/SimpleScheduler.java index 18fd931516..ee7d36e99a 100644 --- a/core/java/src/net/i2p/util/SimpleScheduler.java +++ b/core/java/src/net/i2p/util/SimpleScheduler.java @@ -42,6 +42,7 @@ public class SimpleScheduler { _name = name; _count = 0; _executor = new ScheduledThreadPoolExecutor(THREADS, new CustomThreadFactory()); + _executor.prestartAllCoreThreads(); } /** @@ -90,10 +91,11 @@ public class SimpleScheduler { public Thread newThread(Runnable r) { Thread rv = Executors.defaultThreadFactory().newThread(r); rv.setName(_name + ' ' + (++_count) + '/' + THREADS); - String name = rv.getThreadGroup().getName(); - if(!(name.isEmpty() || name.equals("Main") || name.equals("main"))) { - (new Exception("OWCH! DAMN! Wrong ThreadGroup `" + name +"', `" + rv.getName() + "'")).printStackTrace(); - } +// Uncomment this to test threadgrouping, but we should be all safe now that the constructor preallocates! +// String name = rv.getThreadGroup().getName(); +// if(!name.equals("main")) { +// (new Exception("OWCH! DAMN! Wrong ThreadGroup `" + name +"', `" + rv.getName() + "'")).printStackTrace(); +// } rv.setDaemon(true); return rv; } diff --git a/core/java/src/net/i2p/util/SimpleTimer2.java b/core/java/src/net/i2p/util/SimpleTimer2.java index f74ef1b232..b2af33cf2b 100644 --- a/core/java/src/net/i2p/util/SimpleTimer2.java +++ b/core/java/src/net/i2p/util/SimpleTimer2.java @@ -41,6 +41,7 @@ public class SimpleTimer2 { _name = name; _count = 0; _executor = new CustomScheduledThreadPoolExecutor(THREADS, new CustomThreadFactory()); + _executor.prestartAllCoreThreads(); } /** @@ -67,10 +68,11 @@ public class SimpleTimer2 { public Thread newThread(Runnable r) { Thread rv = Executors.defaultThreadFactory().newThread(r); rv.setName(_name + ' ' + (++_count) + '/' + THREADS); - String name = rv.getThreadGroup().getName(); - if(!(name.isEmpty() || name.equals("Main") || name.equals("main"))) { - (new Exception("OWCH! DAMN! Wrong ThreadGroup `" + name +"', `" + rv.getName() + "'")).printStackTrace(); - } +// Uncomment this to test threadgrouping, but we should be all safe now that the constructor preallocates! +// String name = rv.getThreadGroup().getName(); +// if(!name.equals("main")) { +// (new Exception("OWCH! DAMN! Wrong ThreadGroup `" + name +"', `" + rv.getName() + "'")).printStackTrace(); +// } rv.setDaemon(true); return rv; } diff --git a/history.txt b/history.txt index 0b02fd0ed8..4a4d93e0ac 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,12 @@ +2009-04-07 sponge + * SimpleTimer2, SimpleScheduler fixed so that the threads all run from + The main threadgroup, not in the current possible child threadgroup. + So long as any SimpleTimer2/SimpleScheduler is started *BEFORE* any + child threadgroups, the constructors are threadgroup safe. What would + be super cool is if they were to be all jailed within thier very own + threadgroup too, but, I2P isn't up to the task of this yet. + * Fixes to BOB to ensure the above is true. + 2009-04-06 sponge * Debugging to make SimpleTimer2 and SimpleScheduler easier to debug. * Fix for the config files in the GUI from mathiasdm diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 6ade2ee810..c1d6bdf7c6 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -17,7 +17,7 @@ import net.i2p.CoreVersion; public class RouterVersion { public final static String ID = "$Revision: 1.548 $ $Date: 2008-06-07 23:00:00 $"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 9; + public final static long BUILD = 10; public static void main(String args[]) { System.out.println("I2P Router version: " + VERSION + "-" + BUILD); System.out.println("Router ID: " + RouterVersion.ID);