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
This commit is contained in:
Trustin Lee 2009-06-10 08:56:37 +00:00
parent c0deea647e
commit 734a5a46d4
15 changed files with 180 additions and 94 deletions

View File

@ -35,8 +35,8 @@ import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelState; import org.jboss.netty.channel.ChannelState;
import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.MessageEvent; 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.IoWorkerRunnable;
import org.jboss.netty.util.internal.ThreadRenamingRunnable;
/** /**
* @author The Netty Project (netty-dev@lists.jboss.org) * @author The Netty Project (netty-dev@lists.jboss.org)

View File

@ -48,9 +48,9 @@ import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.logging.InternalLogger; import org.jboss.netty.logging.InternalLogger;
import org.jboss.netty.logging.InternalLoggerFactory; 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.IoWorkerRunnable;
import org.jboss.netty.util.internal.LinkedTransferQueue; import org.jboss.netty.util.internal.LinkedTransferQueue;
import org.jboss.netty.util.internal.ThreadRenamingRunnable;
/** /**
* *

View File

@ -37,8 +37,8 @@ import java.util.concurrent.TimeUnit;
import org.jboss.netty.logging.InternalLogger; import org.jboss.netty.logging.InternalLogger;
import org.jboss.netty.logging.InternalLoggerFactory; 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.SystemPropertyUtil;
import org.jboss.netty.util.internal.ThreadRenamingRunnable;
/** /**
* Provides information which is specific to a NIO service provider * Provides information which is specific to a NIO service provider

View File

@ -43,8 +43,8 @@ import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.logging.InternalLogger; import org.jboss.netty.logging.InternalLogger;
import org.jboss.netty.logging.InternalLoggerFactory; 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.IoWorkerRunnable;
import org.jboss.netty.util.internal.ThreadRenamingRunnable;
/** /**
* *

View File

@ -51,9 +51,9 @@ import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.ReceiveBufferSizePredictor; import org.jboss.netty.channel.ReceiveBufferSizePredictor;
import org.jboss.netty.logging.InternalLogger; import org.jboss.netty.logging.InternalLogger;
import org.jboss.netty.logging.InternalLoggerFactory; 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.IoWorkerRunnable;
import org.jboss.netty.util.internal.LinkedTransferQueue; import org.jboss.netty.util.internal.LinkedTransferQueue;
import org.jboss.netty.util.internal.ThreadRenamingRunnable;
/** /**
* *

View File

@ -36,8 +36,8 @@ import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelState; import org.jboss.netty.channel.ChannelState;
import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.MessageEvent; 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.IoWorkerRunnable;
import org.jboss.netty.util.internal.ThreadRenamingRunnable;
/** /**
* *

View File

@ -35,8 +35,8 @@ import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelState; import org.jboss.netty.channel.ChannelState;
import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.MessageEvent; 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.IoWorkerRunnable;
import org.jboss.netty.util.internal.ThreadRenamingRunnable;
/** /**
* *

View File

@ -40,8 +40,8 @@ import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.logging.InternalLogger; import org.jboss.netty.logging.InternalLogger;
import org.jboss.netty.logging.InternalLoggerFactory; 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.IoWorkerRunnable;
import org.jboss.netty.util.internal.ThreadRenamingRunnable;
/** /**
* *

View File

@ -40,7 +40,6 @@ import org.jboss.netty.logging.InternalLoggerFactory;
import org.jboss.netty.util.internal.ConcurrentIdentityHashMap; import org.jboss.netty.util.internal.ConcurrentIdentityHashMap;
import org.jboss.netty.util.internal.MapBackedSet; import org.jboss.netty.util.internal.MapBackedSet;
import org.jboss.netty.util.internal.ReusableIterator; import org.jboss.netty.util.internal.ReusableIterator;
import org.jboss.netty.util.internal.ThreadRenamingRunnable;
/** /**
* @author The Netty Project (netty-dev@lists.jboss.org) * @author The Netty Project (netty-dev@lists.jboss.org)

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -29,6 +29,7 @@ import java.util.regex.Pattern;
import org.jboss.netty.channel.DefaultChannelPipeline; import org.jboss.netty.channel.DefaultChannelPipeline;
import org.jboss.netty.channel.SimpleChannelHandler; import org.jboss.netty.channel.SimpleChannelHandler;
import org.jboss.netty.util.DebugUtil; import org.jboss.netty.util.DebugUtil;
import org.jboss.netty.util.ThreadRenamingRunnable;
/** /**
* Simplifies an exception stack trace by removing unnecessary * Simplifies an exception stack trace by removing unnecessary
@ -47,8 +48,8 @@ public class StackTraceSimplifier {
private static final Pattern EXCLUDED_STACK_TRACE = private static final Pattern EXCLUDED_STACK_TRACE =
Pattern.compile( Pattern.compile(
"^org\\.jboss\\.netty\\." + "^org\\.jboss\\.netty\\." +
"(util\\.internal\\.(ThreadRenamingRunnable)" + "(util\\.(ThreadRenamingRunnable)" +
"|channel\\.(SimpleChannelHandler|DefaultChannelPipeline.*))$"); "|channel\\.(SimpleChannel(Upstream|Downstream)?Handler|DefaultChannelPipeline.*))$");
/** /**
* Removes unnecessary {@link StackTraceElement}s from the specified * Removes unnecessary {@link StackTraceElement}s from the specified

View File

@ -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);
}
}
}
}

View File

@ -1,7 +1,7 @@
/* /*
* JBoss, Home of Professional Open Source * 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 * by the @author tags. See the COPYRIGHT.txt in the distribution for a
* full listing of individual contributors. * full listing of individual contributors.
* *
@ -20,7 +20,7 @@
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org. * 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.easymock.EasyMock.*;
import static org.junit.Assert.*; import static org.junit.Assert.*;
@ -28,6 +28,7 @@ import static org.junit.Assert.*;
import java.security.Permission; import java.security.Permission;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import org.jboss.netty.util.internal.ImmediateExecutor;
import org.junit.Test; import org.junit.Test;

View File

@ -30,6 +30,7 @@ import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.DefaultChannelPipeline; import org.jboss.netty.channel.DefaultChannelPipeline;
import org.jboss.netty.channel.SimpleChannelHandler; import org.jboss.netty.channel.SimpleChannelHandler;
import org.jboss.netty.util.ThreadRenamingRunnable;
import org.junit.Test; import org.junit.Test;