From 342c97d8ba33512b87d79627c3dbfdf04f9fa42e Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Thu, 27 Mar 2014 15:37:23 +0100 Subject: [PATCH] 430654 - closing client connections can hang worker threads. Prettified usage of NonBlockingThread and added Javadocs. --- .../org/eclipse/jetty/io/SelectorManager.java | 21 +++++---------- .../jetty/util/thread/NonBlockingThread.java | 26 ++++++++++++++++--- 2 files changed, 29 insertions(+), 18 deletions(-) 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 c2dbbd83b7a..fd3c6c6b9ee 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 @@ -204,7 +204,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa ManagedSelector selector = newSelector(i); _selectors[i] = selector; selector.start(); - execute(selector); + execute(new NonBlockingThread(selector)); } } @@ -476,21 +476,14 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa public void run() { _thread = Thread.currentThread(); - final String name = _thread.getName(); + String name = _thread.getName(); try { - NonBlockingThread.runAsNonBlocking(new Runnable() - { - @Override - public void run() - { - _thread.setName(name + "-selector-" + SelectorManager.this.getClass().getSimpleName()+"@"+Integer.toHexString(SelectorManager.this.hashCode())+"/"+_id); - LOG.debug("Starting {} on {}", _thread, this); - while (isRunning()) - select(); - runChanges(); - } - }); + _thread.setName(name + "-selector-" + SelectorManager.this.getClass().getSimpleName()+"@"+Integer.toHexString(SelectorManager.this.hashCode())+"/"+_id); + LOG.debug("Starting {} on {}", _thread, this); + while (isRunning()) + select(); + runChanges(); } finally { diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/NonBlockingThread.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/NonBlockingThread.java index 64076d31174..4fb75c7fb0c 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/NonBlockingThread.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/NonBlockingThread.java @@ -18,20 +18,38 @@ package org.eclipse.jetty.util.thread; -public class NonBlockingThread +/** + * Marker that wraps a Runnable, indicating that it is running in a thread that must not be blocked. + *

+ * Client code can use the thread-local {@link #isNonBlockingThread()} to detect whether they are + * in the context of a non-blocking thread, and perform different actions if that's the case. + */ +public class NonBlockingThread implements Runnable { - private final static ThreadLocal __nonBlockingThread = new ThreadLocal<>(); + private final static ThreadLocal __nonBlockingThread = new ThreadLocal<>(); + + /** + * @return whether the current thread is a thread that must not block. + */ public static boolean isNonBlockingThread() { return Boolean.TRUE.equals(__nonBlockingThread.get()); } - public static void runAsNonBlocking(Runnable runnable) + private final Runnable delegate; + + public NonBlockingThread(Runnable delegate) + { + this.delegate = delegate; + } + + @Override + public void run() { try { __nonBlockingThread.set(Boolean.TRUE); - runnable.run(); + delegate.run(); } finally {