From 27a3ceeb27a7178fa6f5a9504636d2ab1987dd1c Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 17 Oct 2013 12:43:28 +1100 Subject: [PATCH] Optimised SelectorManager to avoid changeQ for interest ops --- .../jetty/io/SelectChannelEndPoint.java | 3 +- .../org/eclipse/jetty/io/SelectorManager.java | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/SelectChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/SelectChannelEndPoint.java index 7f012d9dc1d..b3bf8e8a9a7 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/SelectChannelEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/SelectChannelEndPoint.java @@ -133,7 +133,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements SelectorMa if (_interestOps.compareAndSet(oldInterestOps, newInterestOps)) { LOG.debug("Local interests updated {} -> {} for {}", oldInterestOps, newInterestOps, this); - _selector.submit(_updateTask); + _selector.updateKey(_updateTask); } else { @@ -152,7 +152,6 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements SelectorMa private void setKeyInterests(int oldInterestOps, int newInterestOps) { - assert _selector.isSelectorThread(); LOG.debug("Key interests updated {} -> {}", oldInterestOps, newInterestOps); _key.interestOps(newInterestOps); } diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java b/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java index f14c3b950b4..f711ce6e4f3 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java @@ -59,11 +59,14 @@ import org.eclipse.jetty.util.thread.Scheduler; public abstract class SelectorManager extends AbstractLifeCycle implements Dumpable { protected static final Logger LOG = Log.getLogger(SelectorManager.class); + /** * The default connect timeout, in milliseconds */ public static final int DEFAULT_CONNECT_TIMEOUT = 15000; + private final static boolean __submitKeyUpdates=Boolean.valueOf(System.getProperty("org.eclipse.jetty.io.SelectorManager.SubmitKeyUpdates","FALSE")); + private final Executor executor; private final Scheduler scheduler; private final ManagedSelector[] _selectors; @@ -356,6 +359,39 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa LOG.debug("Stopped {}", this); } + /** + * Submit a task to update a selector key. If the System property + * "org.eclipse.jetty.io.SelectorManager.SubmitKeyUpdates" is set true (default is false), the + * task is passed to {@link #submit(Runnable)}. Otherwise it is run immediately and the selector + * woken up if need be. + * @param update the update to a key + */ + public void updateKey(Runnable update) + { + if (__submitKeyUpdates) + submit(update); + else + { + update.run(); + + out: while (true) + { + switch (_state.get()) + { + case SELECT: + // Avoid multiple wakeup() calls if we the CAS fails + if (!_state.compareAndSet(State.SELECT, State.WAKEUP)) + continue; + wakeup(); + break out; + default: + break out; + } + } + } + + } + /** *

Submits a change to be executed in the selector thread.

*

Changes may be submitted from any thread, and the selector thread woken up