I observed a bottleneck in WebappClassLoaderBase.filter() during a stress test. The reason is, that the method is synchronized. It looks to me, that the reason for the synchronization is only the access to the non-thread safe Matchers packageTriggersPermit and packageTriggersDeny. Since they are not used anywhere else, IMHO one can get away with using a separate Lock object for access to the two. E.g.

Index: WebappClassLoaderBase.java
===================================================================
--- WebappClassLoaderBase.java  (revision 1726388)
+++ WebappClassLoaderBase.java  (working copy)
@@ -191,6 +191,12 @@
// ------------------------------------------------------- Static Variables

     /**
+     * Monitor Object used to synchronize calling
+     * packageTriggersDeny and packageTriggersPermit.
+     */
+    protected final Object packageTriggersLock = new Object();
+
+    /**
* Regular expression of package names which are not allowed to be loaded
      * from a webapp class loader without delegating first.
      */
@@ -2781,7 +2787,7 @@
      * @param name class name
      * @return <code>true</code> if the class should be filtered
      */
-    protected synchronized boolean filter(String name) {
+    protected boolean filter(String name) {

         if (name == null)
             return false;
@@ -2795,16 +2801,17 @@
         else
             return false;

-        packageTriggersPermit.reset(packageName);
-        if (packageTriggersPermit.lookingAt()) {
-            return false;
+        synchronized(packageTriggersLock) {
+            packageTriggersPermit.reset(packageName);
+            if (packageTriggersPermit.lookingAt()) {
+                return false;
+            }
+            packageTriggersDeny.reset(packageName);
+            if (packageTriggersDeny.lookingAt()) {
+                return true;
+            }
         }

-        packageTriggersDeny.reset(packageName);
-        if (packageTriggersDeny.lookingAt()) {
-            return true;
-        }
-
         return false;
     }


Comments on the patch?

In addition:

Since the calls to filter() are in a hot code path, I wonder whether using a more complex code instead of a single regexp could be better. The code should be fast in the common case, which IMHO is the case when the resource name neither starts with javax nor with org.apache. That case could be handled by a simple prefix comparison without regexp.

Only when the resource name starts with javax or org.apache (or org/apache) the various cases to check may make using a regexp be the better decision. Of course such code is a bit harder to maintain, than a single regexp.

I think I'll run a simple micro benchmark to get an idea.

Regards,

Rainer

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to