Fix for part 3 of https://issues.apache.org/bugzilla/show_bug.cgi?id=43683
authormarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Fri, 27 Jun 2008 21:39:27 +0000 (21:39 +0000)
committermarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Fri, 27 Jun 2008 21:39:27 +0000 (21:39 +0000)
This isn't perfect but it narrows the window for the race condition significantly. A perfect fix would require syncing most (all?) of allocate() which is on the critical path.

git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@672397 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/catalina/core/StandardWrapper.java

index 6aec097..b7e58a9 100644 (file)
@@ -766,6 +766,8 @@ public class StandardWrapper
             throw new ServletException
               (sm.getString("standardWrapper.unloading", getName()));
 
+        boolean newInstance = false;
+        
         // If not SingleThreadedModel, return the same instance every time
         if (!singleThreadModel) {
 
@@ -778,6 +780,12 @@ public class StandardWrapper
                                 log.debug("Allocating non-STM instance");
 
                             instance = loadServlet();
+                            // For non-STM, increment here to prevent a race
+                            // condition with unload. Bug 43683, test case #3
+                            if (!singleThreadModel) {
+                                newInstance = true;
+                                countAllocated++;
+                            }
                         } catch (ServletException e) {
                             throw e;
                         } catch (Throwable e) {
@@ -791,10 +799,13 @@ public class StandardWrapper
             if (!singleThreadModel) {
                 if (log.isTraceEnabled())
                     log.trace("  Returning non-STM instance");
-                countAllocated++;
+                // For new instances, count will have been incremented at the
+                // time of creation
+                if (!newInstance) {
+                    countAllocated++;
+                }
                 return (instance);
             }
-
         }
 
         synchronized (instancePool) {