* Console, TunnelControllerGroup: Don't register shutdown hook if ClientAppManager is present

* JettyStart: Fixes for use by plugins
 * RouterAppManager: Add shutdown hook
This commit is contained in:
zzz
2013-04-24 15:45:15 +00:00
parent 57fd46d3a1
commit 813a1981d9
6 changed files with 75 additions and 14 deletions

View File

@ -125,6 +125,8 @@ public class TunnelControllerGroup implements ClientApp {
loadControllers(_configFile); loadControllers(_configFile);
if (_mgr != null) if (_mgr != null)
_mgr.register(this); _mgr.register(this);
// RouterAppManager registers its own shutdown hook
else
_context.addShutdownTask(new Shutdown()); _context.addShutdownTask(new Shutdown());
} }
@ -194,7 +196,9 @@ public class TunnelControllerGroup implements ClientApp {
* *
* @since 0.8.8 * @since 0.8.8
*/ */
public void shutdown() { public synchronized void shutdown() {
if (_state != STARTING && _state != RUNNING)
return;
changeState(STOPPING); changeState(STOPPING);
if (_mgr != null) if (_mgr != null)
_mgr.unregister(this); _mgr.unregister(this);

View File

@ -41,7 +41,6 @@ import org.eclipse.jetty.xml.XmlConfiguration;
*/ */
public class JettyStart implements ClientApp { public class JettyStart implements ClientApp {
private final I2PAppContext _context;
private final ClientAppManager _mgr; private final ClientAppManager _mgr;
private final String[] _args; private final String[] _args;
private final List<LifeCycle> _jettys; private final List<LifeCycle> _jettys;
@ -50,10 +49,12 @@ public class JettyStart implements ClientApp {
/** /**
* All args must be XML file names. * All args must be XML file names.
* Does not support any of the other argument types from org.mortbay.start.Main. * Does not support any of the other argument types from org.mortbay.start.Main.
*
* @param context unused, may be null
* @param mgr may be null e.g. for use in plugins
*/ */
public JettyStart(I2PAppContext context, ClientAppManager mgr, String[] args) throws Exception { public JettyStart(I2PAppContext context, ClientAppManager mgr, String[] args) throws Exception {
_state = UNINITIALIZED; _state = UNINITIALIZED;
_context = context;
_mgr = mgr; _mgr = mgr;
_args = args; _args = args;
_jettys = new ArrayList(args.length); _jettys = new ArrayList(args.length);
@ -100,13 +101,13 @@ public class JettyStart implements ClientApp {
private class Starter extends Thread { private class Starter extends Thread {
public Starter() { public Starter() {
super("JettyStarter"); super("JettyStarter");
changeState(STARTING);
} }
/** /**
* Modified from XmlConfiguration.main() * Modified from XmlConfiguration.main()
*/ */
public void run() { public void run() {
changeState(STARTING);
for (LifeCycle lc : _jettys) { for (LifeCycle lc : _jettys) {
if (!lc.isRunning()) { if (!lc.isRunning()) {
try { try {
@ -118,11 +119,12 @@ public class JettyStart implements ClientApp {
} }
} }
changeState(RUNNING); changeState(RUNNING);
if (_mgr != null)
_mgr.register(JettyStart.this); _mgr.register(JettyStart.this);
} }
} }
public void shutdown(String[] args) { public synchronized void shutdown(String[] args) {
if (_state != RUNNING) if (_state != RUNNING)
return; return;
if (_jettys.isEmpty()) { if (_jettys.isEmpty()) {
@ -135,10 +137,10 @@ public class JettyStart implements ClientApp {
private class Stopper extends Thread { private class Stopper extends Thread {
public Stopper() { public Stopper() {
super("JettyStopper"); super("JettyStopper");
changeState(STOPPING);
} }
public void run() { public void run() {
changeState(STOPPING);
for (LifeCycle lc : _jettys) { for (LifeCycle lc : _jettys) {
if (lc.isRunning()) { if (lc.isRunning()) {
try { try {
@ -170,6 +172,22 @@ public class JettyStart implements ClientApp {
private synchronized void changeState(ClientAppState state, Exception e) { private synchronized void changeState(ClientAppState state, Exception e) {
_state = state; _state = state;
if (_mgr != null)
_mgr.notify(this, state, null, e); _mgr.notify(this, state, null, e);
} }
/**
* For use in a plugin clients.config
* @param args passed to constructor
* @since 0.9.6
*/
public static void main(String[] args) {
try {
new JettyStart(null, null, args);
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
} }

View File

@ -214,15 +214,19 @@ public class RouterConsoleRunner implements RouterApp {
/////// ClientApp methods /////// ClientApp methods
/** @since 0.9.4 */ /** @since 0.9.4 */
public void startup() { public synchronized void startup() {
changeState(STARTING); changeState(STARTING);
startTrayApp(_context); startTrayApp(_context);
startConsole(); startConsole();
} }
/** @since 0.9.4 */ /** @since 0.9.4 */
public void shutdown(String[] args) { public synchronized void shutdown(String[] args) {
if (_state == STOPPED)
return;
changeState(STOPPING); changeState(STOPPING);
if (PluginStarter.pluginsEnabled(_context))
(new I2PAppThread(new PluginStopper(_context), "PluginStopper")).start();
try { try {
_server.stop(); _server.stop();
} catch (Exception ie) {} } catch (Exception ie) {}
@ -653,9 +657,10 @@ public class RouterConsoleRunner implements RouterApp {
t = new I2PAppThread(new PluginStarter(_context), "PluginStarter", true); t = new I2PAppThread(new PluginStarter(_context), "PluginStarter", true);
t.setPriority(Thread.NORM_PRIORITY - 1); t.setPriority(Thread.NORM_PRIORITY - 1);
t.start(); t.start();
_context.addShutdownTask(new PluginStopper(_context));
} }
// stat summarizer registers its own hook // stat summarizer registers its own hook
// RouterAppManager registers its own hook
if (_mgr == null)
_context.addShutdownTask(new ServerShutdown()); _context.addShutdownTask(new ServerShutdown());
ConfigServiceHandler.registerSignalHandler(_context); ConfigServiceHandler.registerSignalHandler(_context);
} }

View File

@ -1,3 +1,8 @@
2013-04-24 zzz
* Console, i2ptunnel: Don't register shutdown hook if ClientAppManager is present
* JettyStart: Fixes for use by plugins
* RouterAppManager: Add shutdown hook
2013-04-23 zzz 2013-04-23 zzz
* Console: Fix Jetty digest auth bug causing repeated password requests * Console: Fix Jetty digest auth bug causing repeated password requests
* i2ptunnel: Block b32.i2p supercookies * i2ptunnel: Block b32.i2p supercookies

View File

@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */ /** deprecated */
public final static String ID = "Monotone"; public final static String ID = "Monotone";
public final static String VERSION = CoreVersion.VERSION; public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 13; public final static long BUILD = 14;
/** for example "-test" */ /** for example "-test" */
public final static String EXTRA = ""; public final static String EXTRA = "";

View File

@ -5,8 +5,10 @@ import java.io.Writer;
import java.util.Arrays; import java.util.Arrays;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import net.i2p.app.*; import net.i2p.app.*;
@ -35,6 +37,7 @@ public class RouterAppManager implements ClientAppManager {
_log = ctx.logManager().getLog(RouterAppManager.class); _log = ctx.logManager().getLog(RouterAppManager.class);
_clients = new ConcurrentHashMap(16); _clients = new ConcurrentHashMap(16);
_registered = new ConcurrentHashMap(8); _registered = new ConcurrentHashMap(8);
ctx.addShutdownTask(new Shutdown());
} }
/** /**
@ -166,6 +169,32 @@ public class RouterAppManager implements ClientAppManager {
return _registered.get(name); return _registered.get(name);
} }
/// end ClientAppManager interface
/**
* @since 0.9.6
*/
public synchronized void shutdown() {
Set<ClientApp> apps = new HashSet(_clients.keySet());
for (ClientApp app : apps) {
ClientAppState state = app.getState();
if (state == RUNNING || state == STARTING) {
try {
app.shutdown(null);
} catch (Throwable t) {}
}
}
}
/**
* @since 0.9.6
*/
public class Shutdown implements Runnable {
public void run() {
shutdown();
}
}
/** /**
* debug * debug
* @since 0.9.6 * @since 0.9.6