public static final String SSL_ATTR_ALLOW_UNSAFE_RENEG =
"allowUnsafeLegacyRenegotiation";
+ private static final int INITIAL_ERROR_DELAY = 50;
+ private static final int MAX_ERROR_DELAY = 1600;
+
// ----------------------------------------------------------------- Fields
} else return -1;
}
-
+ /**
+ * Provides a common approach for sub-classes to handle exceptions where a
+ * delay is required to prevent a Thread from entering a tight loop which
+ * will consume CPU and may also trigger large amounts of logging. For
+ * example, this can happen with the Acceptor thread if the ulimit for open
+ * files is reached.
+ *
+ * @param currentErrorDelay The current delay beign applied on failure
+ * @return The delay to apply on the next failure
+ */
+ protected int handleExceptionWithDelay(int currentErrorDelay) {
+ // Don't delay on first exception
+ if (currentErrorDelay > 0) {
+ try {
+ Thread.sleep(currentErrorDelay);
+ } catch (InterruptedException e) {
+ // Ignore
+ }
+ }
+
+ // On subsequent exceptions, start the delay at 50ms, doubling the delay
+ // on every subsequent exception until the delay reaches 1.6 seconds.
+ if (currentErrorDelay == 0) {
+ return INITIAL_ERROR_DELAY;
+ } else if (currentErrorDelay < MAX_ERROR_DELAY) {
+ return currentErrorDelay * 2;
+ } else {
+ return MAX_ERROR_DELAY;
+ }
+
+ }
// -------------------- SSL related properties --------------------
@Override
public void run() {
+ int errorDelay = 0;
+
// Loop until we receive a shutdown command
while (running) {
try {
//if we have reached max connections, wait
awaitConnection();
- // Accept the next incoming connection from the server socket
- long socket = Socket.accept(serverSock);
+
+ long socket = 0;
+ try {
+ // Accept the next incoming connection from the server
+ // socket
+ socket = Socket.accept(serverSock);
+ } catch (Exception e) {
+ // Introduce delay if necessary
+ errorDelay = handleExceptionWithDelay(errorDelay);
+ // re-throw
+ throw e;
+ }
+ // Successful accept, reset the error delay
+ errorDelay = 0;
+
//increment socket count
countUpConnection();
/*
@Override
public void run() {
+ int errorDelay = 0;
+
// Loop until we receive a shutdown command
while (running) {
}
try {
//if we have reached max connections, wait
- awaitConnection();
- // Accept the next incoming connection from the server socket
- Socket socket = serverSocketFactory.acceptSocket(serverSocket);
-
+ awaitConnection();
+
+ Socket socket = null;
+ try {
+ // Accept the next incoming connection from the server
+ // socket
+ socket = serverSocketFactory.acceptSocket(serverSocket);
+ } catch (IOException ioe) {
+ // Introduce delay if necessary
+ errorDelay = handleExceptionWithDelay(errorDelay);
+ // re-throw
+ throw ioe;
+ }
+ // Successful accept, reset the error delay
+ errorDelay = 0;
+
// Configure the socket
if (setSocketOptions(socket)) {
// Hand this socket off to an appropriate processor
*/
@Override
public void run() {
-
+
+ int errorDelay = 0;
+
// Loop until we receive a shutdown command
while (running) {
try {
//if we have reached max connections, wait
awaitConnection();
- // Accept the next incoming connection from the server socket
- SocketChannel socket = serverSock.accept();
+
+ SocketChannel socket = null;
+ try {
+ // Accept the next incoming connection from the server
+ // socket
+ socket = serverSock.accept();
+ } catch (IOException ioe) {
+ // Introduce delay if necessary
+ errorDelay = handleExceptionWithDelay(errorDelay);
+ // re-throw
+ throw ioe;
+ }
+ // Successful accept, reset the error delay
+ errorDelay = 0;
+
// Hand this socket off to an appropriate processor
//TODO FIXME - this is currently a blocking call, meaning we will be blocking
//further accepts until there is a thread available.
<bug>50780</bug>: Fix memory leak in APR implementation of AJP
connector introduced by the refactoring for <bug>49884</bug>. (markt)
</fix>
+ <fix>
+ If server configuration errors and/or faulty applications caused the
+ ulimit for open files to be reached, the acceptor threads for all
+ connectors could enter a tight loop. This loop consumed CPU and also
+ logged an error message for every iteration of the loop which lead to
+ large log files being generated. The acceptors have been enhanced to
+ better handle this situation. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Jasper">