Author: markt
Date: Sat Feb  2 20:38:29 2013
New Revision: 1441807

URL: http://svn.apache.org/viewvc?rev=1441807&view=rev
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=54513
Multiple bugs in the new Poller implementation (r1433976) when
the endpoint is stopped and then started
 - Ensure old Poller thread stops
 - Ensure old AsyncTimeout thread stops
 - Ensure old sendfile thread stops
 - Ensure sockets in keep-alive are closed

Modified:
    tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java

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=1441807&r1=1441806&r2=1441807&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Sat Feb  2 
20:38:29 2013
@@ -186,6 +186,15 @@ public class AprEndpoint extends Abstrac
 
 
     /**
+     * The socket poller.
+     */
+    protected AsyncTimeout asyncTimeout = null;
+    public AsyncTimeout getAsyncTimeout() {
+        return asyncTimeout;
+    }
+
+
+    /**
      * The static file sender.
      */
     protected Sendfile sendfile = null;
@@ -609,7 +618,8 @@ public class AprEndpoint extends Abstrac
             startAcceptorThreads();
 
             // Start async timeout thread
-            Thread timeoutThread = new Thread(new AsyncTimeout(),
+            asyncTimeout = new AsyncTimeout();
+            Thread timeoutThread = new Thread(asyncTimeout,
                     getName() + "-AsyncTimeout");
             timeoutThread.setPriority(threadPriority);
             timeoutThread.setDaemon(true);
@@ -629,6 +639,8 @@ public class AprEndpoint extends Abstrac
         }
         if (running) {
             running = false;
+            poller.stop();
+            asyncTimeout.stop();
             unlockAccept();
             for (AbstractEndpoint.Acceptor acceptor : acceptors) {
                 long waitLeft = 10000;
@@ -1000,6 +1012,9 @@ public class AprEndpoint extends Abstrac
      * Async timeout thread
      */
     protected class AsyncTimeout implements Runnable {
+
+        private volatile boolean asyncTimeoutRunning = true;
+
         /**
          * The background thread that checks async requests and fires the
          * timeout if there has been no activity.
@@ -1008,7 +1023,7 @@ public class AprEndpoint extends Abstrac
         public void run() {
 
             // Loop until we receive a shutdown command
-            while (running) {
+            while (asyncTimeoutRunning) {
                 try {
                     Thread.sleep(1000);
                 } catch (InterruptedException e) {
@@ -1029,7 +1044,7 @@ public class AprEndpoint extends Abstrac
                 }
 
                 // Loop if endpoint is paused
-                while (paused && running) {
+                while (paused && asyncTimeoutRunning) {
                     try {
                         Thread.sleep(1000);
                     } catch (InterruptedException e) {
@@ -1039,6 +1054,11 @@ public class AprEndpoint extends Abstrac
 
             }
         }
+
+
+        protected void stop() {
+            asyncTimeoutRunning = false;
+        }
     }
 
 
@@ -1260,6 +1280,8 @@ public class AprEndpoint extends Abstrac
         public int getConnectionCount() { return connectionCount; }
 
 
+        private volatile boolean pollerRunning = true;
+
         /**
          * Create the poller. With some versions of APR, the maximum poller 
size
          * will be 62 (recompiling APR is necessary to remove this limitation).
@@ -1316,6 +1338,12 @@ public class AprEndpoint extends Abstrac
 
         }
 
+
+        protected void stop() {
+            pollerRunning = false;
+        }
+
+
         /**
          * Destroy the poller.
          */
@@ -1325,6 +1353,7 @@ public class AprEndpoint extends Abstrac
             // still in the poller can cause problems
             try {
                 synchronized (this) {
+                    this.notify();
                     this.wait(pollTime / 1000);
                 }
             } catch (InterruptedException e) {
@@ -1351,7 +1380,7 @@ public class AprEndpoint extends Abstrac
                                 Long.valueOf(desc[n*2+1])).isComet();
                         if (!comet || (comet && !processSocket(
                                 desc[n*2+1], SocketStatus.STOP))) {
-                            destroySocket(desc[n*2+1]);
+                            destroySocket(desc[n*2+1], true);
                         }
                     }
                 }
@@ -1537,7 +1566,7 @@ public class AprEndpoint extends Abstrac
 
             int maintain = 0;
             // Loop until we receive a shutdown command
-            while (running) {
+            while (pollerRunning) {
 
                 // Loop if endpoint is paused
                 while (paused) {
@@ -1548,10 +1577,11 @@ public class AprEndpoint extends Abstrac
                     }
                 }
                 // Check timeouts if the poller is empty
-                while (connectionCount < 1 && addList.size() < 1) {
+                while (pollerRunning && connectionCount < 1 &&
+                        addList.size() < 1) {
                     // Reset maintain time.
                     try {
-                        if (getSoTimeout() > 0 && running) {
+                        if (getSoTimeout() > 0 && pollerRunning) {
                             maintain();
                         }
                         synchronized (this) {
@@ -1722,7 +1752,7 @@ public class AprEndpoint extends Abstrac
                     }
 
                     // Process socket timeouts
-                    if (getSoTimeout() > 0 && maintain++ > 1000 && running) {
+                    if (getSoTimeout() > 0 && maintain++ > 1000 && 
pollerRunning) {
                         // This works and uses only one timeout mechanism for 
everything, but the
                         // non event poller might be a bit faster by using the 
old maintain.
                         maintain = 0;
@@ -1785,6 +1815,8 @@ public class AprEndpoint extends Abstrac
 
         protected ArrayList<SendfileData> addS;
 
+        private volatile boolean sendfileRunning = true;
+
         /**
          * Create the sendfile poller. With some versions of APR, the maximum
          * poller size will be 62 (recompiling APR is necessary to remove this
@@ -1814,6 +1846,7 @@ public class AprEndpoint extends Abstrac
          * Destroy the poller.
          */
         protected void destroy() {
+            sendfileRunning = false;
             // Wait for polltime before doing anything, so that the poller 
threads
             // exit, otherwise parallel destruction of sockets which are still
             // in the poller can cause problems
@@ -1920,7 +1953,7 @@ public class AprEndpoint extends Abstrac
 
             long maintainTime = 0;
             // Loop until we receive a shutdown command
-            while (running) {
+            while (sendfileRunning) {
 
                 // Loop if endpoint is paused
                 while (paused) {
@@ -2036,7 +2069,7 @@ public class AprEndpoint extends Abstrac
                     }
                     // Call maintain for the sendfile poller
                     if (getSoTimeout() > 0 &&
-                            maintainTime > 1000000L && running) {
+                            maintainTime > 1000000L && sendfileRunning) {
                         rv = Poll.maintain(sendfilePollset, desc, false);
                         maintainTime = 0;
                         if (rv > 0) {



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

Reply via email to