shutdown fixes

pull/13/head
knaccc 5 years ago
parent d1b4021d71
commit 48afd8543e

@ -108,7 +108,7 @@ public class Controller {
tunnelRemoveButton.setOnAction(e->{ tunnelRemoveButton.setOnAction(e->{
Tunnel t = tunnelsTableView.getSelectionModel().getSelectedItem(); Tunnel t = tunnelsTableView.getSelectionModel().getSelectedItem();
getRouterWrapper().getTunnelControl().getTunnelList().removeTunnel(t); getRouterWrapper().getTunnelControl().getTunnelList().removeTunnel(t);
t.destroy(); t.destroy(false);
tunnelRemoveButton.setDisable(true); tunnelRemoveButton.setDisable(true);
}); });
@ -188,7 +188,7 @@ public class Controller {
getEepSiteTunnel().start(); getEepSiteTunnel().start();
} }
else { else {
getEepSiteTunnel().destroy(); getEepSiteTunnel().destroy(false);
} }
} }
}); });
@ -247,7 +247,7 @@ public class Controller {
else { else {
masterToggle.setImage(new Image("org/getmonero/i2p/zero/gui/toggle-off.png")); masterToggle.setImage(new Image("org/getmonero/i2p/zero/gui/toggle-off.png"));
statusLabel.setVisible(false); statusLabel.setVisible(false);
routerWrapper.stop(); routerWrapper.stop(false);
tunnelTableList.clear(); tunnelTableList.clear();
tunnelAddButton.setDisable(true); tunnelAddButton.setDisable(true);
} }

@ -61,7 +61,7 @@ public class Gui extends Application {
@Override @Override
public void stop() throws Exception { public void stop() throws Exception {
isStopping = true; isStopping = true;
if(controller.getRouterWrapper().isStarted()) controller.getRouterWrapper().stop(); if(controller.getRouterWrapper().isStarted()) controller.getRouterWrapper().stop(true);
} }
public boolean isStopping() { public boolean isStopping() {

@ -37,7 +37,7 @@ public class Main {
RouterWrapper routerWrapper = new RouterWrapper(p); RouterWrapper routerWrapper = new RouterWrapper(p);
routerWrapper.start(); routerWrapper.start();
Runtime.getRuntime().addShutdownHook(new Thread(()->routerWrapper.stop())); Runtime.getRuntime().addShutdownHook(new Thread(()->routerWrapper.stop(true)));
} }

@ -98,18 +98,20 @@ public class RouterWrapper {
} }
public void stop() { public void stop(boolean fastStop) {
if(!started) return; if(!started) return;
started = false; started = false;
tunnelControl.stop(); tunnelControl.stop(fastStop);
System.out.println("I2P router will shut down gracefully"); System.out.println("I2P router will shut down gracefully");
router.shutdownGracefully(); router.shutdownGracefully();
// don't wait more than 2 seconds for shutdown. If tunnels are still opening, they can pause for up to 20 seconds, which is too long if(fastStop) {
new Thread(()->{ // don't wait more than 2 seconds for shutdown. If tunnels are still opening, they can pause for up to 20 seconds, which is too long
try { Thread.sleep(2000); } catch (InterruptedException e) {} new Thread(() -> {
System.exit(0); try { Thread.sleep(2000); } catch (InterruptedException e) {}
}).start(); System.exit(0);
}).start();
}
} }
long lastTriggerTimestamp = 0; long lastTriggerTimestamp = 0;

@ -184,11 +184,15 @@ public class TunnelControl implements Runnable {
return tunnel==null ? "opening" : "open"; return tunnel==null ? "opening" : "open";
} }
public boolean getEnabled() { return enabled; } public boolean getEnabled() { return enabled; }
public void destroy() { public void destroy(boolean fastDestroy) {
new Thread(()->{ new Thread(()->{
// subsequent line commented out, because the tunnels will sleep for 20 seconds at a time, which is too long // tunnels may sleep for 20 seconds while waiting to open. we may be in a hurry
// while(tunnel==null) { try { Thread.sleep(100); } catch (InterruptedException e) {} } // wait for tunnel to be established before closing it if(!fastDestroy) {
if(tunnel!=null) tunnel.runClose(new String[]{"forced", "all"}, tunnel); while(tunnel==null) { try { Thread.sleep(100); } catch (InterruptedException e) {} } // wait for tunnel to be established before closing it
}
if(tunnel!=null) {
tunnel.runClose(new String[]{"forced", "all"}, tunnel);
}
}).start(); }).start();
} }
} }
@ -300,10 +304,10 @@ public class TunnelControl implements Runnable {
} }
@Override @Override
public void destroy() { public void destroy(boolean fastDestroy) {
try { try {
server.stop(); server.stop();
super.destroy(); super.destroy(fastDestroy);
} }
catch (Exception e) { catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
@ -508,7 +512,7 @@ public class TunnelControl implements Runnable {
case "server.destroy": { case "server.destroy": {
String dest = args[1]; String dest = args[1];
tunnelList.getTunnelsCopyStream().filter(t -> t.getType().equals("server") && ((ServerTunnel) t).dest.equals(dest)).forEach(t -> { tunnelList.getTunnelsCopyStream().filter(t -> t.getType().equals("server") && ((ServerTunnel) t).dest.equals(dest)).forEach(t -> {
t.destroy(); t.destroy(false);
tunnelList.removeTunnel(t); tunnelList.removeTunnel(t);
}); });
out.println("OK"); out.println("OK");
@ -536,7 +540,7 @@ public class TunnelControl implements Runnable {
case "client.destroy": { case "client.destroy": {
int port = Integer.parseInt(args[1]); int port = Integer.parseInt(args[1]);
tunnelList.getTunnelsCopyStream().filter(t->t.getType().equals("client") && ((ClientTunnel) t).port == port).forEach(t->{ tunnelList.getTunnelsCopyStream().filter(t->t.getType().equals("client") && ((ClientTunnel) t).port == port).forEach(t->{
t.destroy(); t.destroy(false);
tunnelList.removeTunnel(t); tunnelList.removeTunnel(t);
}); });
out.println("OK"); out.println("OK");
@ -561,7 +565,7 @@ public class TunnelControl implements Runnable {
case "socks.destroy": { case "socks.destroy": {
int port = Integer.parseInt(args[1]); int port = Integer.parseInt(args[1]);
tunnelList.getTunnelsCopyStream().filter(t -> t.getType().equals("socks") && ((SocksTunnel) t).port == port).forEach(t -> { tunnelList.getTunnelsCopyStream().filter(t -> t.getType().equals("socks") && ((SocksTunnel) t).port == port).forEach(t -> {
t.destroy(); t.destroy(false);
tunnelList.removeTunnel(t); tunnelList.removeTunnel(t);
}); });
out.println("OK"); out.println("OK");
@ -585,7 +589,7 @@ public class TunnelControl implements Runnable {
case "http.destroy": { case "http.destroy": {
int port = Integer.parseInt(args[1]); int port = Integer.parseInt(args[1]);
tunnelList.getTunnelsCopyStream().filter(t -> t.getType().equals("http") && ((SocksTunnel) t).port == port).forEach(t -> { tunnelList.getTunnelsCopyStream().filter(t -> t.getType().equals("http") && ((SocksTunnel) t).port == port).forEach(t -> {
t.destroy(); t.destroy(false);
tunnelList.removeTunnel(t); tunnelList.removeTunnel(t);
}); });
out.println("OK"); out.println("OK");
@ -601,7 +605,7 @@ public class TunnelControl implements Runnable {
case "all.destroy": { case "all.destroy": {
tunnelList.getTunnelsCopyStream().forEach(t -> { tunnelList.getTunnelsCopyStream().forEach(t -> {
t.destroy(); t.destroy(false);
tunnelList.removeTunnel(t); tunnelList.removeTunnel(t);
}); });
out.println("OK"); out.println("OK");
@ -648,10 +652,10 @@ public class TunnelControl implements Runnable {
} }
public void stop() { public void stop(boolean fastStop) {
stopping = true; stopping = true;
try { try {
getTunnelList().tunnels.forEach(TunnelControl.Tunnel::destroy); getTunnelList().tunnels.forEach(t->t.destroy(fastStop));
controlServerSocket.close(); controlServerSocket.close();
} }
catch (Exception e) { catch (Exception e) {

Loading…
Cancel
Save