You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2013/12/16 21:39:19 UTC
svn commit: r1551340 - in /tomcat/trunk/java/org/apache/tomcat/util:
net/AbstractEndpoint.java net/AprEndpoint.java net/JIoEndpoint.java
net/NioEndpoint.java threads/TaskThreadFactory.java
Author: markt
Date: Mon Dec 16 20:39:19 2013
New Revision: 1551340
URL: http://svn.apache.org/r1551340
Log:
Performance improvement
The context class loader was set in *Endpoint#processSocket() in case a new thread was created since this method may be triggered from web application code and that in turn would trigger a memory leak since the thread would end up with the web app class loader as its context class loader. However, this is only an issue when creating threads and since getting the current class loader is expensive, move this code to where threads are created rather than calling it on every call to *Endpoint#processSocket().
This appears (on my fairly unscientific tests) to remove ~5% of the overhead from all request processing.
Modified:
tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java
tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java
tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
tomcat/trunk/java/org/apache/tomcat/util/threads/TaskThreadFactory.java
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java?rev=1551340&r1=1551339&r2=1551340&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java Mon Dec 16 20:39:19 2013
@@ -20,7 +20,6 @@ import java.io.File;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
-import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -97,22 +96,6 @@ public abstract class AbstractEndpoint<S
}
- protected static class PrivilegedSetTccl implements PrivilegedAction<Void> {
-
- private ClassLoader cl;
-
- PrivilegedSetTccl(ClassLoader cl) {
- this.cl = cl;
- }
-
- @Override
- public Void run() {
- Thread.currentThread().setContextClassLoader(cl);
- return null;
- }
- }
-
-
private static final int INITIAL_ERROR_DELAY = 50;
private static final int MAX_ERROR_DELAY = 1600;
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java?rev=1551340&r1=1551339&r2=1551340&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Mon Dec 16 20:39:19 2013
@@ -17,8 +17,6 @@
package org.apache.tomcat.util.net;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -892,26 +890,7 @@ public class AprEndpoint extends Abstrac
SocketProcessor proc = new SocketProcessor(socket, status);
Executor executor = getExecutor();
if (dispatch && executor != null) {
- ClassLoader loader = Thread.currentThread().getContextClassLoader();
- try {
- //threads should not be created by the webapp classloader
- if (Constants.IS_SECURITY_ENABLED) {
- PrivilegedAction<Void> pa = new PrivilegedSetTccl(
- getClass().getClassLoader());
- AccessController.doPrivileged(pa);
- } else {
- Thread.currentThread().setContextClassLoader(
- getClass().getClassLoader());
- }
- executor.execute(proc);
- } finally {
- if (Constants.IS_SECURITY_ENABLED) {
- PrivilegedAction<Void> pa = new PrivilegedSetTccl(loader);
- AccessController.doPrivileged(pa);
- } else {
- Thread.currentThread().setContextClassLoader(loader);
- }
- }
+ executor.execute(proc);
} else {
proc.run();
}
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java?rev=1551340&r1=1551339&r2=1551340&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java Mon Dec 16 20:39:19 2013
@@ -22,8 +22,6 @@ import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.util.Iterator;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executor;
@@ -566,31 +564,11 @@ public class JIoEndpoint extends Abstrac
SocketProcessor proc = new SocketProcessor(socket,status);
Executor executor = getExecutor();
if (dispatch && executor != null) {
- ClassLoader loader = Thread.currentThread().getContextClassLoader();
- try {
- //threads should not be created by the webapp classloader
- if (Constants.IS_SECURITY_ENABLED) {
- PrivilegedAction<Void> pa =
- new PrivilegedSetTccl(
- getClass().getClassLoader());
- AccessController.doPrivileged(pa);
- } else {
- Thread.currentThread().setContextClassLoader(
- getClass().getClassLoader());
- }
- // During shutdown, executor may be null - avoid NPE
- if (!running) {
- return;
- }
- getExecutor().execute(proc);
- } finally {
- if (Constants.IS_SECURITY_ENABLED) {
- PrivilegedAction<Void> pa = new PrivilegedSetTccl(loader);
- AccessController.doPrivileged(pa);
- } else {
- Thread.currentThread().setContextClassLoader(loader);
- }
+ // During shutdown, executor may be null - avoid NPE
+ if (!running) {
+ return;
}
+ getExecutor().execute(proc);
} else {
proc.run();
}
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java?rev=1551340&r1=1551339&r2=1551340&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java Mon Dec 16 20:39:19 2013
@@ -32,8 +32,6 @@ import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.WritableByteChannel;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
@@ -631,26 +629,7 @@ public class NioEndpoint extends Abstrac
else sc.reset(socket,status);
Executor executor = getExecutor();
if (dispatch && executor != null) {
- ClassLoader loader = Thread.currentThread().getContextClassLoader();
- try {
- //threads should not be created by the webapp classloader
- if (Constants.IS_SECURITY_ENABLED) {
- PrivilegedAction<Void> pa = new PrivilegedSetTccl(
- getClass().getClassLoader());
- AccessController.doPrivileged(pa);
- } else {
- Thread.currentThread().setContextClassLoader(
- getClass().getClassLoader());
- }
- executor.execute(sc);
- } finally {
- if (Constants.IS_SECURITY_ENABLED) {
- PrivilegedAction<Void> pa = new PrivilegedSetTccl(loader);
- AccessController.doPrivileged(pa);
- } else {
- Thread.currentThread().setContextClassLoader(loader);
- }
- }
+ executor.execute(sc);
} else {
sc.run();
}
@@ -872,7 +851,7 @@ public class NioEndpoint extends Abstrac
private volatile boolean close = false;
private long nextExpiration = 0;//optimize expiration handling
- private AtomicLong wakeupCounter = new AtomicLong(0l);
+ private AtomicLong wakeupCounter = new AtomicLong(0);
private volatile int keyCount = 0;
Modified: tomcat/trunk/java/org/apache/tomcat/util/threads/TaskThreadFactory.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/threads/TaskThreadFactory.java?rev=1551340&r1=1551339&r2=1551340&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/threads/TaskThreadFactory.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/threads/TaskThreadFactory.java Mon Dec 16 20:39:19 2013
@@ -16,19 +16,24 @@
*/
package org.apache.tomcat.util.threads;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.tomcat.util.net.Constants;
/**
- * Simple task thread factory to use to create threads for an executor implementation.
- * @author fhanik
- *
+ * Simple task thread factory to use to create threads for an executor
+ * implementation.
*/
public class TaskThreadFactory implements ThreadFactory {
+
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
private final boolean daemon;
private final int threadPriority;
+
public TaskThreadFactory(String namePrefix, boolean daemon, int priority) {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
@@ -39,10 +44,44 @@ public class TaskThreadFactory implement
@Override
public Thread newThread(Runnable r) {
- TaskThread t = new TaskThread(group, r, namePrefix + threadNumber.getAndIncrement());
- t.setDaemon(daemon);
- t.setPriority(threadPriority);
- return t;
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ try {
+ // Threads should not be created by the webapp classloader
+ if (Constants.IS_SECURITY_ENABLED) {
+ PrivilegedAction<Void> pa = new PrivilegedSetTccl(
+ getClass().getClassLoader());
+ AccessController.doPrivileged(pa);
+ } else {
+ Thread.currentThread().setContextClassLoader(
+ getClass().getClassLoader());
+ }
+ TaskThread t = new TaskThread(group, r, namePrefix + threadNumber.getAndIncrement());
+ t.setDaemon(daemon);
+ t.setPriority(threadPriority);
+ return t;
+ } finally {
+ if (Constants.IS_SECURITY_ENABLED) {
+ PrivilegedAction<Void> pa = new PrivilegedSetTccl(loader);
+ AccessController.doPrivileged(pa);
+ } else {
+ Thread.currentThread().setContextClassLoader(loader);
+ }
+ }
}
+
+ private static class PrivilegedSetTccl implements PrivilegedAction<Void> {
+
+ private ClassLoader cl;
+
+ PrivilegedSetTccl(ClassLoader cl) {
+ this.cl = cl;
+ }
+
+ @Override
+ public Void run() {
+ Thread.currentThread().setContextClassLoader(cl);
+ return null;
+ }
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org