remm        01/09/06 18:23:25

  Modified:    catalina/src/share/org/apache/catalina/loader
                        WebappClassLoader.java
  Log:
  - Should make the classloading fully thread safe (apparently synchronizing on
    the defineClass is not enough).
  - The critical path of findResourceInternal or findClassInternal should not be
    synchronized for performance reasons, because it is called very often (unlike
    the call to defineClass which only happens once).
  - I assume Peter will tell me it still doesn't work (in which case I would appreciate
    a test case) ;-)
  
  Revision  Changes    Path
  1.14      +23 -9     
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java
  
  Index: WebappClassLoader.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- WebappClassLoader.java    2001/08/28 18:12:37     1.13
  +++ WebappClassLoader.java    2001/09/07 01:23:25     1.14
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java,v
 1.13 2001/08/28 18:12:37 remm Exp $
  - * $Revision: 1.13 $
  - * $Date: 2001/08/28 18:12:37 $
  + * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java,v
 1.14 2001/09/07 01:23:25 remm Exp $
  + * $Revision: 1.14 $
  + * $Date: 2001/09/07 01:23:25 $
    *
    * ====================================================================
    *
  @@ -123,7 +123,7 @@
    *
    * @author Remy Maucherat
    * @author Craig R. McClanahan
  - * @version $Revision: 1.13 $ $Date: 2001/08/28 18:12:37 $
  + * @version $Revision: 1.14 $ $Date: 2001/09/07 01:23:25 $
    */
   public class WebappClassLoader
       extends URLClassLoader
  @@ -1482,11 +1482,17 @@
           }
   
           synchronized(this) {
  -            clazz = defineClass(name, entry.binaryContent, 0,
  -                                entry.binaryContent.length, codeSource);
  +            // Since all threads use the same ResourceEntry instance, it is
  +            // the one which will contain the class
  +            if (entry.loadedClass == null) {
  +                clazz = defineClass(name, entry.binaryContent, 0,
  +                                    entry.binaryContent.length, codeSource);
  +                entry.loadedClass = clazz;
  +            } else {
  +                clazz = entry.loadedClass;
  +            }
           }
   
  -        entry.loadedClass = clazz;
   
           return clazz;
   
  @@ -1635,8 +1641,16 @@
           entry.binaryContent = binaryContent;
   
           // Add the entry in the local resource repository
  -        synchronized (resourceEntries) {
  -            resourceEntries.put(name, entry);
  +        synchronized (this) {
  +            // Ensures that all the threads which may be in a race to load
  +            // a particular class all end up with the same ResourceEntry
  +            // instance
  +            ResourceEntry entry2 = (ResourceEntry) resourceEntries.get(name);
  +            if (entry2 == null) {
  +                resourceEntries.put(name, entry);
  +            } else {
  +                entry = entry2;
  +            }
           }
   
           return entry;
  
  
  

Reply via email to