diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java index 2a2e0dac18b..bedc36ef842 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java @@ -162,6 +162,8 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo // we are not interested in further selecting _key.interestOps(0); + if (!_dispatched) + updateKey(); return; } diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java index 21823c8297b..8c6db52fb60 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java @@ -444,7 +444,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa // Stopped concurrently ? if (selector == null) return; - + // Make any key changes required Object change; int changes=_changes.size(); @@ -585,15 +585,6 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa // Log and dump some status _paused=true; LOG.warn("Selector {} is too busy, pausing!",this); - final SelectSet set = this; - SelectorManager.this.dispatch( - new Runnable(){ - public void run() - { - System.err.println(set+":\n"+set.dump()); - } - public String toString() {return "Dump-"+super.toString();} - }); } } } @@ -991,6 +982,16 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa dumpto.add(key.attachment()+" - - "); } } + + /* ------------------------------------------------------------ */ + public String toString() + { + String s=super.toString()+" "+SelectorManager.this.getState(); + Selector selector=_selector; + if (selector!=null && selector.isOpen()) + s+=",k="+selector.keys().size()+",s="+selector.selectedKeys().size(); + return s; + } } /* ------------------------------------------------------------ */ diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SslConnection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SslConnection.java index 1c472f5ddd9..b26f0dde1c0 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SslConnection.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SslConnection.java @@ -238,6 +238,21 @@ public class SslConnection extends AbstractConnection implements AsyncConnection } + /* ------------------------------------------------------------ */ + @Override + public void onIdleExpired() + { + try + { + _sslEndPoint.shutdownOutput(); + } + catch (IOException e) + { + LOG.warn(e); + super.onIdleExpired(); + } + } + /* ------------------------------------------------------------ */ public void onInputShutdown() throws IOException { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ShutdownHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ShutdownHandler.java index 810f48993d9..aa4edeb7f61 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ShutdownHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ShutdownHandler.java @@ -68,6 +68,8 @@ public class ShutdownHandler extends AbstractHandler private final Server _server; private boolean _exitJvm = false; + + /** * Creates a listener that lets the server be shut down remotely (but only from localhost). @@ -110,18 +112,24 @@ public class ShutdownHandler extends AbstractHandler LOG.info("Shutting down by request from " + getRemoteAddr(request)); - try + new Thread() { - shutdownServer(); - } - catch (InterruptedException e) - { - LOG.ignore(e); - } - catch (Exception e) - { - throw new RuntimeException("Shutting down server",e); - } + public void run () + { + try + { + shutdownServer(); + } + catch (InterruptedException e) + { + LOG.ignore(e); + } + catch (Exception e) + { + throw new RuntimeException("Shutting down server",e); + } + } + }.start(); } private boolean requestFromLocalhost(HttpServletRequest request) diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ShutdownHandlerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ShutdownHandlerTest.java index 02dae765e79..0d46cc17496 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ShutdownHandlerTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ShutdownHandlerTest.java @@ -14,12 +14,18 @@ package org.eclipse.jetty.server.handler; //======================================================================== import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.util.component.AbstractLifeCycle; +import org.eclipse.jetty.util.component.LifeCycle; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; @@ -48,8 +54,36 @@ public class ShutdownHandlerTest public void shutdownServerWithCorrectTokenAndIPTest() throws Exception { setDefaultExpectations(); + final CountDownLatch countDown = new CountDownLatch(1); + server.addLifeCycleListener(new AbstractLifeCycle.Listener () + { + + public void lifeCycleStarting(LifeCycle event) + { + } + + public void lifeCycleStarted(LifeCycle event) + { + } + + public void lifeCycleFailure(LifeCycle event, Throwable cause) + { + } + + public void lifeCycleStopping(LifeCycle event) + { + } + + public void lifeCycleStopped(LifeCycle event) + { + countDown.countDown(); + } + + }); shutdownHandler.handle("/shutdown",null,request,response); - assertEquals("Server should be stopped","STOPPED",server.getState()); + boolean stopped = countDown.await(1000, TimeUnit.MILLISECONDS); //wait up to 1 sec to stop + assertTrue("Server lifecycle stop listener called", stopped); + assertEquals("Server should be stopped","STOPPED",server.getState()); } @Test