From 734a5a46d481040ebda476feec3680de9d2593b8 Mon Sep 17 00:00:00 2001 From: Trustin Lee Date: Wed, 10 Jun 2009 08:56:37 +0000 Subject: [PATCH] Fixed issue: NETTY-172 Let user choose the I/O thread names * Added ThreadNameDeterminer * Moved ThreadRenamingRunnable from org.jboss.netty.util.internal to org.jboss.netty.util because it should be accessible by user --- ...HttpTunnelingClientSocketPipelineSink.java | 2 +- .../nio/NioClientSocketPipelineSink.java | 2 +- .../socket/nio/NioProviderMetadata.java | 2 +- .../nio/NioServerSocketPipelineSink.java | 2 +- .../netty/channel/socket/nio/NioWorker.java | 2 +- .../oio/OioClientSocketPipelineSink.java | 2 +- .../socket/oio/OioDatagramPipelineSink.java | 2 +- .../oio/OioServerSocketPipelineSink.java | 2 +- .../jboss/netty/util/HashedWheelTimer.java | 1 - .../netty/util/ThreadNameDeterminer.java | 32 +++++ .../netty/util/ThreadRenamingRunnable.java | 133 ++++++++++++++++++ .../util/internal/StackTraceSimplifier.java | 5 +- .../util/internal/ThreadRenamingRunnable.java | 81 ----------- .../ThreadRenamingRunnableTest.java | 5 +- .../internal/StackTraceSimplifierTest.java | 1 + 15 files changed, 180 insertions(+), 94 deletions(-) create mode 100644 src/main/java/org/jboss/netty/util/ThreadNameDeterminer.java create mode 100644 src/main/java/org/jboss/netty/util/ThreadRenamingRunnable.java delete mode 100644 src/main/java/org/jboss/netty/util/internal/ThreadRenamingRunnable.java rename src/test/java/org/jboss/netty/util/{internal => }/ThreadRenamingRunnableTest.java (95%) diff --git a/src/main/java/org/jboss/netty/channel/socket/http/HttpTunnelingClientSocketPipelineSink.java b/src/main/java/org/jboss/netty/channel/socket/http/HttpTunnelingClientSocketPipelineSink.java index 5c4f49287d..7ec122ce74 100644 --- a/src/main/java/org/jboss/netty/channel/socket/http/HttpTunnelingClientSocketPipelineSink.java +++ b/src/main/java/org/jboss/netty/channel/socket/http/HttpTunnelingClientSocketPipelineSink.java @@ -35,8 +35,8 @@ import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelState; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.util.ThreadRenamingRunnable; import org.jboss.netty.util.internal.IoWorkerRunnable; -import org.jboss.netty.util.internal.ThreadRenamingRunnable; /** * @author The Netty Project (netty-dev@lists.jboss.org) diff --git a/src/main/java/org/jboss/netty/channel/socket/nio/NioClientSocketPipelineSink.java b/src/main/java/org/jboss/netty/channel/socket/nio/NioClientSocketPipelineSink.java index 56a6293e87..4bc6f8659a 100644 --- a/src/main/java/org/jboss/netty/channel/socket/nio/NioClientSocketPipelineSink.java +++ b/src/main/java/org/jboss/netty/channel/socket/nio/NioClientSocketPipelineSink.java @@ -48,9 +48,9 @@ import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.logging.InternalLogger; import org.jboss.netty.logging.InternalLoggerFactory; +import org.jboss.netty.util.ThreadRenamingRunnable; import org.jboss.netty.util.internal.IoWorkerRunnable; import org.jboss.netty.util.internal.LinkedTransferQueue; -import org.jboss.netty.util.internal.ThreadRenamingRunnable; /** * diff --git a/src/main/java/org/jboss/netty/channel/socket/nio/NioProviderMetadata.java b/src/main/java/org/jboss/netty/channel/socket/nio/NioProviderMetadata.java index f4b1c51e5c..c287cf6f1f 100644 --- a/src/main/java/org/jboss/netty/channel/socket/nio/NioProviderMetadata.java +++ b/src/main/java/org/jboss/netty/channel/socket/nio/NioProviderMetadata.java @@ -37,8 +37,8 @@ import java.util.concurrent.TimeUnit; import org.jboss.netty.logging.InternalLogger; import org.jboss.netty.logging.InternalLoggerFactory; +import org.jboss.netty.util.ThreadRenamingRunnable; import org.jboss.netty.util.internal.SystemPropertyUtil; -import org.jboss.netty.util.internal.ThreadRenamingRunnable; /** * Provides information which is specific to a NIO service provider diff --git a/src/main/java/org/jboss/netty/channel/socket/nio/NioServerSocketPipelineSink.java b/src/main/java/org/jboss/netty/channel/socket/nio/NioServerSocketPipelineSink.java index b99212a4a9..e2ae029554 100644 --- a/src/main/java/org/jboss/netty/channel/socket/nio/NioServerSocketPipelineSink.java +++ b/src/main/java/org/jboss/netty/channel/socket/nio/NioServerSocketPipelineSink.java @@ -43,8 +43,8 @@ import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.logging.InternalLogger; import org.jboss.netty.logging.InternalLoggerFactory; +import org.jboss.netty.util.ThreadRenamingRunnable; import org.jboss.netty.util.internal.IoWorkerRunnable; -import org.jboss.netty.util.internal.ThreadRenamingRunnable; /** * diff --git a/src/main/java/org/jboss/netty/channel/socket/nio/NioWorker.java b/src/main/java/org/jboss/netty/channel/socket/nio/NioWorker.java index 3549d33000..35d28e833c 100644 --- a/src/main/java/org/jboss/netty/channel/socket/nio/NioWorker.java +++ b/src/main/java/org/jboss/netty/channel/socket/nio/NioWorker.java @@ -51,9 +51,9 @@ import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.ReceiveBufferSizePredictor; import org.jboss.netty.logging.InternalLogger; import org.jboss.netty.logging.InternalLoggerFactory; +import org.jboss.netty.util.ThreadRenamingRunnable; import org.jboss.netty.util.internal.IoWorkerRunnable; import org.jboss.netty.util.internal.LinkedTransferQueue; -import org.jboss.netty.util.internal.ThreadRenamingRunnable; /** * diff --git a/src/main/java/org/jboss/netty/channel/socket/oio/OioClientSocketPipelineSink.java b/src/main/java/org/jboss/netty/channel/socket/oio/OioClientSocketPipelineSink.java index 13bfb48652..15174b75fe 100644 --- a/src/main/java/org/jboss/netty/channel/socket/oio/OioClientSocketPipelineSink.java +++ b/src/main/java/org/jboss/netty/channel/socket/oio/OioClientSocketPipelineSink.java @@ -36,8 +36,8 @@ import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelState; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.util.ThreadRenamingRunnable; import org.jboss.netty.util.internal.IoWorkerRunnable; -import org.jboss.netty.util.internal.ThreadRenamingRunnable; /** * diff --git a/src/main/java/org/jboss/netty/channel/socket/oio/OioDatagramPipelineSink.java b/src/main/java/org/jboss/netty/channel/socket/oio/OioDatagramPipelineSink.java index 2a4f7a47fb..a454c50046 100644 --- a/src/main/java/org/jboss/netty/channel/socket/oio/OioDatagramPipelineSink.java +++ b/src/main/java/org/jboss/netty/channel/socket/oio/OioDatagramPipelineSink.java @@ -35,8 +35,8 @@ import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelState; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.util.ThreadRenamingRunnable; import org.jboss.netty.util.internal.IoWorkerRunnable; -import org.jboss.netty.util.internal.ThreadRenamingRunnable; /** * diff --git a/src/main/java/org/jboss/netty/channel/socket/oio/OioServerSocketPipelineSink.java b/src/main/java/org/jboss/netty/channel/socket/oio/OioServerSocketPipelineSink.java index 85957e3b94..834dfe88cd 100644 --- a/src/main/java/org/jboss/netty/channel/socket/oio/OioServerSocketPipelineSink.java +++ b/src/main/java/org/jboss/netty/channel/socket/oio/OioServerSocketPipelineSink.java @@ -40,8 +40,8 @@ import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.logging.InternalLogger; import org.jboss.netty.logging.InternalLoggerFactory; +import org.jboss.netty.util.ThreadRenamingRunnable; import org.jboss.netty.util.internal.IoWorkerRunnable; -import org.jboss.netty.util.internal.ThreadRenamingRunnable; /** * diff --git a/src/main/java/org/jboss/netty/util/HashedWheelTimer.java b/src/main/java/org/jboss/netty/util/HashedWheelTimer.java index 58766bc0cc..71e9a30ad9 100644 --- a/src/main/java/org/jboss/netty/util/HashedWheelTimer.java +++ b/src/main/java/org/jboss/netty/util/HashedWheelTimer.java @@ -40,7 +40,6 @@ import org.jboss.netty.logging.InternalLoggerFactory; import org.jboss.netty.util.internal.ConcurrentIdentityHashMap; import org.jboss.netty.util.internal.MapBackedSet; import org.jboss.netty.util.internal.ReusableIterator; -import org.jboss.netty.util.internal.ThreadRenamingRunnable; /** * @author The Netty Project (netty-dev@lists.jboss.org) diff --git a/src/main/java/org/jboss/netty/util/ThreadNameDeterminer.java b/src/main/java/org/jboss/netty/util/ThreadNameDeterminer.java new file mode 100644 index 0000000000..91ce0e994c --- /dev/null +++ b/src/main/java/org/jboss/netty/util/ThreadNameDeterminer.java @@ -0,0 +1,32 @@ +/* + * JBoss, Home of Professional Open Source + * + * Copyright 2009, Red Hat Middleware LLC, and individual contributors + * by the @author tags. See the COPYRIGHT.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.netty.util; + +/** + * @author The Netty Project (netty-dev@lists.jboss.org) + * @author Trustin Lee (tlee@redhat.com) + * @version $Rev$, $Date$ + */ +public interface ThreadNameDeterminer { + String determineThreadName(String oldThreadName, String proposedThreadName) throws Exception; +} diff --git a/src/main/java/org/jboss/netty/util/ThreadRenamingRunnable.java b/src/main/java/org/jboss/netty/util/ThreadRenamingRunnable.java new file mode 100644 index 0000000000..53e54f6c5c --- /dev/null +++ b/src/main/java/org/jboss/netty/util/ThreadRenamingRunnable.java @@ -0,0 +1,133 @@ +/* + * JBoss, Home of Professional Open Source + * + * Copyright 2009, Red Hat Middleware LLC, and individual contributors + * by the @author tags. See the COPYRIGHT.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.netty.util; + +import org.jboss.netty.logging.InternalLogger; +import org.jboss.netty.logging.InternalLoggerFactory; + + +/** + * Meta {@link Runnable} that changes the current thread name and reverts it + * back when its execution ends. + * + * @author The Netty Project (netty-dev@lists.jboss.org) + * @author Trustin Lee (tlee@redhat.com) + * + * @version $Rev$, $Date$ + * + */ +public class ThreadRenamingRunnable implements Runnable { + + private static final InternalLogger logger = + InternalLoggerFactory.getInstance(ThreadRenamingRunnable.class); + + private static volatile ThreadNameDeterminer threadNameDeterminer = + new ThreadNameDeterminer() { + public String determineThreadName( + String oldThreadName, String newThreadName) throws Exception { + return newThreadName; + } + }; + + /** + * Returns the {@link ThreadNameDeterminer} which is used to determine the + * new thread name. + */ + public static ThreadNameDeterminer getThreadNameDeterminer() { + return threadNameDeterminer; + } + + /** + * Sets the {@link ThreadNameDeterminer} which is used to determine the new + * thread name. + */ + public static void setThreadNameDeterminer(ThreadNameDeterminer threadNameDeterminer) { + if (threadNameDeterminer == null) { + throw new NullPointerException("threadNameDeterminer"); + } + ThreadRenamingRunnable.threadNameDeterminer = threadNameDeterminer; + } + + private final Runnable runnable; + private final String proposedThreadName; + + /** + * Creates a new instance which wraps the specified {@code runnable} + * and changes the thread name to the specified thread name when the + * specified {@code runnable} is running. + */ + public ThreadRenamingRunnable(Runnable runnable, String proposedThreadName) { + if (runnable == null) { + throw new NullPointerException("runnable"); + } + if (proposedThreadName == null) { + throw new NullPointerException("proposedThreadName"); + } + this.runnable = runnable; + this.proposedThreadName = proposedThreadName; + } + + public void run() { + final Thread currentThread = Thread.currentThread(); + final String oldThreadName = currentThread.getName(); + final String newThreadName = getNewThreadName(oldThreadName); + + // Change the thread name before starting the actual runnable. + boolean renamed = false; + if (!oldThreadName.equals(newThreadName)) { + try { + currentThread.setName(newThreadName); + renamed = true; + } catch (SecurityException e) { + logger.debug( + "Failed to rename a thread " + + "due to security restriction.", e); + } + } + + // Run the actual runnable and revert the name back when it ends. + try { + runnable.run(); + } finally { + if (renamed) { + // Revert the name back if the current thread was renamed. + // We do not check the exception here because we know it works. + currentThread.setName(oldThreadName); + } + } + } + + private String getNewThreadName(String oldThreadName) { + String newThreadName = null; + + try { + newThreadName = + getThreadNameDeterminer().determineThreadName( + oldThreadName, proposedThreadName); + } catch (Throwable t) { + logger.warn("Failed to determine the thread name", t); + } + + return newThreadName == null? oldThreadName : newThreadName; + } +} diff --git a/src/main/java/org/jboss/netty/util/internal/StackTraceSimplifier.java b/src/main/java/org/jboss/netty/util/internal/StackTraceSimplifier.java index 3db5408b2c..352d963881 100644 --- a/src/main/java/org/jboss/netty/util/internal/StackTraceSimplifier.java +++ b/src/main/java/org/jboss/netty/util/internal/StackTraceSimplifier.java @@ -29,6 +29,7 @@ import java.util.regex.Pattern; import org.jboss.netty.channel.DefaultChannelPipeline; import org.jboss.netty.channel.SimpleChannelHandler; import org.jboss.netty.util.DebugUtil; +import org.jboss.netty.util.ThreadRenamingRunnable; /** * Simplifies an exception stack trace by removing unnecessary @@ -47,8 +48,8 @@ public class StackTraceSimplifier { private static final Pattern EXCLUDED_STACK_TRACE = Pattern.compile( "^org\\.jboss\\.netty\\." + - "(util\\.internal\\.(ThreadRenamingRunnable)" + - "|channel\\.(SimpleChannelHandler|DefaultChannelPipeline.*))$"); + "(util\\.(ThreadRenamingRunnable)" + + "|channel\\.(SimpleChannel(Upstream|Downstream)?Handler|DefaultChannelPipeline.*))$"); /** * Removes unnecessary {@link StackTraceElement}s from the specified diff --git a/src/main/java/org/jboss/netty/util/internal/ThreadRenamingRunnable.java b/src/main/java/org/jboss/netty/util/internal/ThreadRenamingRunnable.java deleted file mode 100644 index 2369361be7..0000000000 --- a/src/main/java/org/jboss/netty/util/internal/ThreadRenamingRunnable.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * JBoss, Home of Professional Open Source - * - * Copyright 2008, Red Hat Middleware LLC, and individual contributors - * by the @author tags. See the COPYRIGHT.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ -package org.jboss.netty.util.internal; - - -/** - * Meta {@link Runnable} that changes the current thread name and reverts it - * back when its execution ends. - * - * @author The Netty Project (netty-dev@lists.jboss.org) - * @author Trustin Lee (tlee@redhat.com) - * - * @version $Rev$, $Date$ - * - */ -public class ThreadRenamingRunnable implements Runnable { - - private final Runnable runnable; - private final String threadName; - - /** - * Creates a new instance which wraps the specified {@code runnable} - * and changes the thread name to the specified thread name when the - * specified {@code runnable} is running. - */ - public ThreadRenamingRunnable(Runnable runnable, String threadName) { - if (runnable == null) { - throw new NullPointerException("runnable"); - } - if (threadName == null) { - throw new NullPointerException("threadName"); - } - this.runnable = runnable; - this.threadName = threadName; - } - - public void run() { - final Thread currentThread = Thread.currentThread(); - final String oldThreadName = currentThread.getName(); - - // Change the thread name before starting the actual runnable. - boolean renamed = false; - try { - currentThread.setName(threadName); - renamed = true; - } catch (SecurityException e) { - // Probably SecurityException. - } - - // Run the actual runnable and revert the name back when it ends. - try { - runnable.run(); - } finally { - if (renamed) { - // Revert the name back if the current thread was renamed. - // We do not check the exception here because we know it works. - currentThread.setName(oldThreadName); - } - } - } -} diff --git a/src/test/java/org/jboss/netty/util/internal/ThreadRenamingRunnableTest.java b/src/test/java/org/jboss/netty/util/ThreadRenamingRunnableTest.java similarity index 95% rename from src/test/java/org/jboss/netty/util/internal/ThreadRenamingRunnableTest.java rename to src/test/java/org/jboss/netty/util/ThreadRenamingRunnableTest.java index 261cc237f4..cfda328c36 100644 --- a/src/test/java/org/jboss/netty/util/internal/ThreadRenamingRunnableTest.java +++ b/src/test/java/org/jboss/netty/util/ThreadRenamingRunnableTest.java @@ -1,7 +1,7 @@ /* * JBoss, Home of Professional Open Source * - * Copyright 2008, Red Hat Middleware LLC, and individual contributors + * Copyright 2009, Red Hat Middleware LLC, and individual contributors * by the @author tags. See the COPYRIGHT.txt in the distribution for a * full listing of individual contributors. * @@ -20,7 +20,7 @@ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ -package org.jboss.netty.util.internal; +package org.jboss.netty.util; import static org.easymock.EasyMock.*; import static org.junit.Assert.*; @@ -28,6 +28,7 @@ import static org.junit.Assert.*; import java.security.Permission; import java.util.concurrent.Executor; +import org.jboss.netty.util.internal.ImmediateExecutor; import org.junit.Test; diff --git a/src/test/java/org/jboss/netty/util/internal/StackTraceSimplifierTest.java b/src/test/java/org/jboss/netty/util/internal/StackTraceSimplifierTest.java index dbceb2e5c7..902452823b 100644 --- a/src/test/java/org/jboss/netty/util/internal/StackTraceSimplifierTest.java +++ b/src/test/java/org/jboss/netty/util/internal/StackTraceSimplifierTest.java @@ -30,6 +30,7 @@ import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.DefaultChannelPipeline; import org.jboss.netty.channel.SimpleChannelHandler; +import org.jboss.netty.util.ThreadRenamingRunnable; import org.junit.Test;