tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ma...@apache.org
Subject svn commit: r1530216 - in /tomcat/tc7.0.x/trunk: ./ java/org/apache/catalina/loader/WebappClassLoader.java webapps/docs/config/context.xml
Date Tue, 08 Oct 2013 10:34:20 GMT
Author: markt
Date: Tue Oct  8 10:34:19 2013
New Revision: 1530216

URL: http://svn.apache.org/r1530216
Log:
Fix an intermittent failure with TestWebappClassLoaderExecutorMemoryLeak.
If the executor threads did not stop quickly enough, Thread.stop() was used. Sometimes this
resulted in the executor not shutting down and the test failing. This makes using clearReferencesStopThreads
marginally safer.

Modified:
    tomcat/tc7.0.x/trunk/   (props changed)
    tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java
    tomcat/tc7.0.x/trunk/webapps/docs/config/context.xml

Propchange: tomcat/tc7.0.x/trunk/
------------------------------------------------------------------------------
  Merged /tomcat/trunk:r1529549,1530213

Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java?rev=1530216&r1=1530215&r2=1530216&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java Tue Oct  8
10:34:19 2013
@@ -2223,6 +2223,7 @@ public class WebappClassLoader
     @SuppressWarnings("deprecation") // thread.stop()
     private void clearReferencesThreads() {
         Thread[] threads = getThreads();
+        List<Thread> executorThreadsToStop = new ArrayList<Thread>();
 
         // Iterate over the set of threads
         for (Thread thread : threads) {
@@ -2281,6 +2282,7 @@ public class WebappClassLoader
 
                     // If the thread has been started via an executor, try
                     // shutting down the executor
+                    boolean usingExecutor = false;
                     try {
 
                         // Runnable wrapped by Thread
@@ -2313,6 +2315,7 @@ public class WebappClassLoader
                             Object executor = executorField.get(target);
                             if (executor instanceof ThreadPoolExecutor) {
                                 ((ThreadPoolExecutor) executor).shutdownNow();
+                                usingExecutor = true;
                             }
                         }
                     } catch (SecurityException e) {
@@ -2333,14 +2336,46 @@ public class WebappClassLoader
                                 thread.getName(), contextName), e);
                     }
 
-                    // This method is deprecated and for good reason. This is
-                    // very risky code but is the only option at this point.
-                    // A *very* good reason for apps to do this clean-up
-                    // themselves.
-                    thread.stop();
+                    if (usingExecutor) {
+                        // Executor may take a short time to stop all the
+                        // threads. Make a note of threads that should be
+                        // stopped and check them at the end of the method.
+                        executorThreadsToStop.add(thread);
+                    } else {
+                        // This method is deprecated and for good reason. This
+                        // is very risky code but is the only option at this
+                        // point. A *very* good reason for apps to do this
+                        // clean-up themselves.
+                        thread.stop();
+                    }
                 }
             }
         }
+
+        // If thread stopping is enabled, executor threads should have been
+        // stopped above when the executor was shut down but that depends on the
+        // thread correctly handling the interrupt. Give all the executor
+        // threads a few seconds shutdown and if they are still running
+        // Give threads up to 2 seconds to shutdown
+        int count = 0;
+        for (Thread t : executorThreadsToStop) {
+            while (t.isAlive() && count < 100) {
+                try {
+                    Thread.sleep(20);
+                } catch (InterruptedException e) {
+                    // Quit the while loop
+                    break;
+                }
+                count++;
+            }
+            if (t.isAlive()) {
+                // This method is deprecated and for good reason. This is
+                // very risky code but is the only option at this point.
+                // A *very* good reason for apps to do this clean-up
+                // themselves.
+                t.stop();
+            }
+        }
     }
 
 

Modified: tomcat/tc7.0.x/trunk/webapps/docs/config/context.xml
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/config/context.xml?rev=1530216&r1=1530215&r2=1530216&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/config/context.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/config/context.xml Tue Oct  8 10:34:19 2013
@@ -714,7 +714,10 @@
         is likely to result in instability. As such, enabling this should be
         viewed as an option of last resort in a development environment and is
         not recommended in a production environment. If not specified, the
-        default value of <code>false</code> will be used.</p>
+        default value of <code>false</code> will be used. If this feature is
+        enabled, web applications may take up to two seconds longer to stop as
+        executor threads are given up to two seconds to stop gracefully before
+        <code>Thread.stop()</code> is called on any remaining threads.</p>
       </attribute>
 
       <attribute name="clearReferencesStopTimerThreads" required = "false">



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


Mime
View raw message