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: [email protected]
For additional commands, e-mail: [email protected]