diff --git a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/Http2Server.java b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/Http2Server.java
index cd001135f49..8b1ceb3dc66 100644
--- a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/Http2Server.java
+++ b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/Http2Server.java
@@ -20,8 +20,10 @@
package org.eclipse.jetty.embedded;
import java.io.IOException;
+import java.lang.management.ManagementFactory;
import java.util.Date;
import java.util.EnumSet;
+
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
@@ -39,6 +41,7 @@ import javax.servlet.http.HttpSession;
import org.eclipse.jetty.alpn.ALPN;
import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory;
import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
+import org.eclipse.jetty.jmx.MBeanContainer;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.NegotiatingServerConnectionFactory;
@@ -63,6 +66,10 @@ public class Http2Server
{
Server server = new Server();
+ MBeanContainer mbContainer = new MBeanContainer(
+ ManagementFactory.getPlatformMBeanServer());
+ server.addBean(mbContainer);
+
ServletContextHandler context = new ServletContextHandler(server, "/",ServletContextHandler.SESSIONS);
context.setResourceBase("src/main/resources/docroot");
context.addFilter(PushSessionCacheFilter.class,"/*",EnumSet.of(DispatcherType.REQUEST));
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java
index 38edc2bd2af..dc6576d4bf3 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java
@@ -27,8 +27,10 @@ import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
+import java.util.List;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
@@ -37,6 +39,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.jetty.util.ConcurrentArrayQueue;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
+import org.eclipse.jetty.util.component.ContainerLifeCycle;
+import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.ExecutionStrategy;
@@ -49,16 +53,16 @@ import org.eclipse.jetty.util.thread.SpinLock;
* happen for registered channels. When events happen, it notifies the {@link EndPoint} associated
* with the channel.
*/
-public class ManagedSelector extends AbstractLifeCycle implements Runnable//, Dumpable TODO
+public class ManagedSelector extends AbstractLifeCycle implements Runnable, Dumpable
{
private static final Logger LOG = Log.getLogger(ManagedSelector.class);
private final SpinLock _lock = new SpinLock();
+ private boolean _selecting=false;
private final Queue _actions = new ConcurrentArrayQueue<>();
private final SelectorManager _selectorManager;
private final int _id;
private final ExecutionStrategy _strategy;
- private State _state = State.PROCESSING;
private Selector _selector;
public ManagedSelector(SelectorManager selectorManager, int id)
@@ -94,9 +98,14 @@ public class ManagedSelector extends AbstractLifeCycle implements Runnable//, Du
{
if (LOG.isDebugEnabled())
LOG.debug("Stopping {}", this);
- Stop stop = new Stop();
- submit(stop);
- stop.await(getStopTimeout());
+ CloseEndPoints close_endps = new CloseEndPoints();
+ submit(close_endps);
+ close_endps.await(getStopTimeout());
+ super.doStop();
+ CloseSelector close_selector = new CloseSelector();
+ submit(close_selector);
+ close_selector.await(getStopTimeout());
+
if (LOG.isDebugEnabled())
LOG.debug("Stopped {}", this);
}
@@ -109,12 +118,11 @@ public class ManagedSelector extends AbstractLifeCycle implements Runnable//, Du
try (SpinLock.Lock lock = _lock.lock())
{
_actions.offer(change);
- if (_state == State.SELECTING)
+ if (_selecting)
{
_selector.wakeup();
- // Move to PROCESSING now, so other submit()
- // calls will avoid the extra select wakeup.
- _state = State.PROCESSING;
+ // To avoid the extra select wakeup.
+ _selecting=false;
}
}
}
@@ -181,7 +189,8 @@ public class ManagedSelector extends AbstractLifeCycle implements Runnable//, Du
action = _actions.poll();
if (action == null)
{
- _state = State.SELECTING;
+ // No more actions, so we need to select
+ _selecting=true;
return null;
}
}
@@ -212,21 +221,26 @@ public class ManagedSelector extends AbstractLifeCycle implements Runnable//, Du
{
try
{
- if (LOG.isDebugEnabled())
- LOG.debug("Selector loop waiting on select");
- int selected = _selector.select();
- if (LOG.isDebugEnabled())
- LOG.debug("Selector loop woken up from select, {}/{} selected", selected, _selector.keys().size());
-
- try (SpinLock.Lock lock = _lock.lock())
+ Selector selector=_selector;
+ if (selector!=null && selector.isOpen())
{
- _state = State.PROCESSING;
+ if (LOG.isDebugEnabled())
+ LOG.debug("Selector loop waiting on select");
+ int selected = selector.select();
+ if (LOG.isDebugEnabled())
+ LOG.debug("Selector loop woken up from select, {}/{} selected", selected, selector.keys().size());
+
+ try (SpinLock.Lock lock = _lock.lock())
+ {
+ // finished selecting
+ _selecting=false;
+ }
+
+ _keys = selector.selectedKeys();
+ _cursor = _keys.iterator();
+
+ return true;
}
-
- _keys = _selector.selectedKeys();
- _cursor = _keys.iterator();
-
- return true;
}
catch (Throwable x)
{
@@ -235,8 +249,8 @@ public class ManagedSelector extends AbstractLifeCycle implements Runnable//, Du
LOG.warn(x);
else
LOG.debug(x);
- return false;
}
+ return false;
}
private Runnable processSelected()
@@ -252,6 +266,7 @@ public class ManagedSelector extends AbstractLifeCycle implements Runnable//, Du
if (attachment instanceof SelectableEndPoint)
{
// Try to produce a task
+ @SuppressWarnings("resource")
SelectableEndPoint selectable = (SelectableEndPoint)attachment;
Runnable task = selectable.onSelected();
if (task != null)
@@ -403,7 +418,7 @@ public class ManagedSelector extends AbstractLifeCycle implements Runnable//, Du
_selectorManager.connectionClosed(connection);
_selectorManager.endPointClosed(endPoint);
}
-/*
+
@Override
public String dump()
{
@@ -428,20 +443,6 @@ public class ManagedSelector extends AbstractLifeCycle implements Runnable//, Du
}
}
- public void dumpKeysState(List