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-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to