Author: markt
Date: Fri Jun 13 20:21:32 2014
New Revision: 1602510

URL: http://svn.apache.org/r1602510
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=56518
Do not attempt an NIO write if a thread has been interrupted as it can lead to 
a connection limit leak

Modified:
    tomcat/tc7.0.x/trunk/   (props changed)
    tomcat/tc7.0.x/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java
    tomcat/tc7.0.x/trunk/java/org/apache/coyote/AbstractProcessor.java
    tomcat/tc7.0.x/trunk/java/org/apache/coyote/Adapter.java
    tomcat/tc7.0.x/trunk/java/org/apache/coyote/LocalStrings.properties
    tomcat/tc7.0.x/trunk/java/org/apache/coyote/Processor.java
    tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java
    tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java
    tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpNioProcessor.java
    tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpProcessor.java
    
tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java
    tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java
    tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java
    
tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/upgrade/AbstractProcessor.java
    
tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessor.java
    tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java
    tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/NioChannel.java
    tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
    tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java
    tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/SocketStatus.java
    
tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/res/LocalStrings.properties
    tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml

Propchange: tomcat/tc7.0.x/trunk/
------------------------------------------------------------------------------
  Merged /tomcat/trunk:r1602198

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java?rev=1602510&r1=1602509&r2=1602510&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java 
Fri Jun 13 20:21:32 2014
@@ -469,6 +469,34 @@ public class CoyoteAdapter implements Ad
 
 
     @Override
+    public void errorDispatch(org.apache.coyote.Request req,
+            org.apache.coyote.Response res) {
+        Request request = (Request) req.getNote(ADAPTER_NOTES);
+        Response response = (Response) res.getNote(ADAPTER_NOTES);
+
+        if (request != null && request.getMappingData().context != null) {
+            ((Context) request.getMappingData().context).logAccess(
+                    request, response,
+                    System.currentTimeMillis() - req.getStartTime(),
+                    false);
+        } else {
+            log(req, res, System.currentTimeMillis() - req.getStartTime());
+        }
+
+        if (request != null) {
+            request.recycle();
+        }
+
+        if (response != null) {
+            response.recycle();
+        }
+
+        res.recycle();
+        res.recycle();
+    }
+
+
+    @Override
     public void log(org.apache.coyote.Request req,
             org.apache.coyote.Response res, long time) {
 

Modified: tomcat/tc7.0.x/trunk/java/org/apache/coyote/AbstractProcessor.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/coyote/AbstractProcessor.java?rev=1602510&r1=1602509&r2=1602510&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/coyote/AbstractProcessor.java 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/coyote/AbstractProcessor.java Fri Jun 
13 20:21:32 2014
@@ -69,8 +69,20 @@ public abstract class AbstractProcessor<
      * Update the current error state to the new error state if the new error
      * state is more severe than the current error state.
      */
-    protected void setErrorState(ErrorState errorState) {
+    protected void setErrorState(ErrorState errorState, Throwable t) {
+        boolean blockIo = this.errorState.isIoAllowed() && 
!errorState.isIoAllowed();
         this.errorState = this.errorState.getMostSevere(errorState);
+        if (blockIo && !ContainerThreadMarker.isContainerThread()) {
+            // The error occurred on a non-container thread which means not all
+            // of the necessary clean-up will have been completed. Dispatch to
+            // a container thread to do the clean-up. Need to do it this way to
+            // ensure that all the necessary clean-up is performed.
+            if (response.getStatus() < 400) {
+                response.setStatus(500);
+            }
+            
getLog().info(sm.getString("abstractProcessor.nonContainerThreadError"), t);
+            getEndpoint().processSocketAsync(socketWrapper, 
SocketStatus.CLOSE_NOW);
+        }
     }
 
 
@@ -157,6 +169,11 @@ public abstract class AbstractProcessor<
     }
 
     @Override
+    public void errorDispatch() {
+        getAdapter().errorDispatch(request, response);
+    }
+
+    @Override
     public abstract boolean isComet();
 
     @Override

Modified: tomcat/tc7.0.x/trunk/java/org/apache/coyote/Adapter.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/coyote/Adapter.java?rev=1602510&r1=1602509&r2=1602510&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/coyote/Adapter.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/coyote/Adapter.java Fri Jun 13 
20:21:32 2014
@@ -51,6 +51,8 @@ public interface Adapter {
     public boolean asyncDispatch(Request req,Response res, SocketStatus status)
             throws Exception;
 
+    public void errorDispatch(Request request, Response response);
+
     public void log(Request req, Response res, long time);
 
     /**

Modified: tomcat/tc7.0.x/trunk/java/org/apache/coyote/LocalStrings.properties
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/coyote/LocalStrings.properties?rev=1602510&r1=1602509&r2=1602510&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/coyote/LocalStrings.properties 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/coyote/LocalStrings.properties Fri Jun 
13 20:21:32 2014
@@ -16,6 +16,8 @@ abstractConnectionHandler.error=Error re
 abstractConnectionHandler.ioexception.debug=IOExceptions are normal, ignored
 abstractConnectionHandler.socketexception.debug=SocketExceptions are normal, 
ignored
 
+abstractProcessor.nonContainerThreadError=An error occurred in processing 
while on a non-container thread. The connection will be closed immediately
+
 abstractProtocolHandler.getAttribute=Get attribute [{0}] with value [{1}]
 abstractProtocolHandler.setAttribute=Set attribute [{0}] with value [{1}]
 abstractProtocolHandler.init=Initializing ProtocolHandler [{0}]

Modified: tomcat/tc7.0.x/trunk/java/org/apache/coyote/Processor.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/coyote/Processor.java?rev=1602510&r1=1602509&r2=1602510&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/coyote/Processor.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/coyote/Processor.java Fri Jun 13 
20:21:32 2014
@@ -54,6 +54,8 @@ public interface Processor<S> {
     HttpUpgradeHandler getHttpUpgradeHandler();
     SocketState upgradeDispatch(SocketStatus status) throws IOException;
     
+    void errorDispatch();
+
     boolean isComet();
     boolean isAsync();
     boolean isUpgrade();

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java?rev=1602510&r1=1602509&r2=1602510&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java 
Fri Jun 13 20:21:32 2014
@@ -319,13 +319,13 @@ public abstract class AbstractAjpProcess
             try {
                 prepareResponse();
             } catch (IOException e) {
-                setErrorState(ErrorState.CLOSE_NOW);
+                setErrorState(ErrorState.CLOSE_NOW, e);
             }
 
             try {
                 flush(false);
             } catch (IOException e) {
-                setErrorState(ErrorState.CLOSE_NOW);
+                setErrorState(ErrorState.CLOSE_NOW, e);
             }
             break;
         }
@@ -335,7 +335,7 @@ public abstract class AbstractAjpProcess
                 try {
                     prepareResponse();
                 } catch (IOException e) {
-                    setErrorState(ErrorState.CLOSE_NOW);
+                    setErrorState(ErrorState.CLOSE_NOW, e);
                     return;
                 }
             }
@@ -343,7 +343,7 @@ public abstract class AbstractAjpProcess
             try {
                 flush(true);
             } catch (IOException e) {
-                setErrorState(ErrorState.CLOSE_NOW);
+                setErrorState(ErrorState.CLOSE_NOW, e);
             }
             break;
         }
@@ -354,7 +354,7 @@ public abstract class AbstractAjpProcess
         case DISABLE_SWALLOW_INPUT: {
             // TODO: Do not swallow request input but
             // make sure we are closing the connection
-            setErrorState(ErrorState.CLOSE_CLEAN);
+            setErrorState(ErrorState.CLOSE_CLEAN, null);
             break;
         }
         case CLOSE: {
@@ -365,7 +365,7 @@ public abstract class AbstractAjpProcess
             try {
                 finish();
             } catch (IOException e) {
-                setErrorState(ErrorState.CLOSE_NOW);
+                setErrorState(ErrorState.CLOSE_NOW, e);
             }
             break;
         }
@@ -494,7 +494,7 @@ public abstract class AbstractAjpProcess
         case CLOSE_NOW: {
             // Prevent further writes to the response
             swallowResponse = true;
-            setErrorState(ErrorState.CLOSE_NOW);
+            setErrorState(ErrorState.CLOSE_NOW, null);
             break;
         }
         }
@@ -508,14 +508,14 @@ public abstract class AbstractAjpProcess
         try {
             rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
             if(!getAdapter().asyncDispatch(request, response, status)) {
-                setErrorState(ErrorState.CLOSE_NOW);
+                setErrorState(ErrorState.CLOSE_NOW, null);
             }
             resetTimeouts();
         } catch (InterruptedIOException e) {
-            setErrorState(ErrorState.CLOSE_NOW);
+            setErrorState(ErrorState.CLOSE_NOW, e);
         } catch (Throwable t) {
             ExceptionUtils.handleThrowable(t);
-            setErrorState(ErrorState.CLOSE_NOW);
+            setErrorState(ErrorState.CLOSE_NOW, t);
             getLog().error(sm.getString("http11processor.request.process"), t);
         } finally {
             if (getErrorState().isError()) {
@@ -761,7 +761,7 @@ public abstract class AbstractAjpProcess
                 long cl = vMB.getLong();
                 if (contentLengthSet) {
                     response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
-                    setErrorState(ErrorState.CLOSE_CLEAN);
+                    setErrorState(ErrorState.CLOSE_CLEAN, null);
                 } else {
                     contentLengthSet = true;
                     // Set the content-length header for the request
@@ -879,7 +879,7 @@ public abstract class AbstractAjpProcess
                     secret = true;
                     if (!tmpMB.equals(requiredSecret)) {
                         response.setStatus(403);
-                        setErrorState(ErrorState.CLOSE_CLEAN);
+                        setErrorState(ErrorState.CLOSE_CLEAN, null);
                     }
                 }
                 break;
@@ -895,7 +895,7 @@ public abstract class AbstractAjpProcess
         // Check if secret was submitted if required
         if ((requiredSecret != null) && !secret) {
             response.setStatus(403);
-            setErrorState(ErrorState.CLOSE_CLEAN);
+            setErrorState(ErrorState.CLOSE_CLEAN, null);
         }
 
         // Check for a full URI (including protocol://host:port/)
@@ -946,7 +946,7 @@ public abstract class AbstractAjpProcess
                 request.serverName().duplicate(request.localName());
             } catch (IOException e) {
                 response.setStatus(400);
-                setErrorState(ErrorState.CLOSE_CLEAN);
+                setErrorState(ErrorState.CLOSE_CLEAN, e);
             }
             return;
         }
@@ -996,7 +996,7 @@ public abstract class AbstractAjpProcess
                     // Invalid character
                     // 400 - Bad request
                     response.setStatus(400);
-                    setErrorState(ErrorState.CLOSE_CLEAN);
+                    setErrorState(ErrorState.CLOSE_CLEAN, null);
                     break;
                 }
                 port = port + (charValue * mult);
@@ -1112,7 +1112,7 @@ public abstract class AbstractAjpProcess
             try {
                 prepareResponse();
             } catch (IOException e) {
-                setErrorState(ErrorState.CLOSE_NOW);
+                setErrorState(ErrorState.CLOSE_NOW, e);
                 return;
             }
         }
@@ -1196,7 +1196,7 @@ public abstract class AbstractAjpProcess
                 try {
                     prepareResponse();
                 } catch (IOException e) {
-                    setErrorState(ErrorState.CLOSE_NOW);
+                    setErrorState(ErrorState.CLOSE_NOW, e);
                 }
             }
 

Modified: tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java?rev=1602510&r1=1602509&r2=1602510&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpAprProcessor.java Fri 
Jun 13 20:21:32 2014
@@ -132,7 +132,7 @@ public class AjpAprProcessor extends Abs
                     cping = true;
                     if (Socket.send(socketRef, pongMessageArray, 0,
                             pongMessageArray.length) < 0) {
-                        setErrorState(ErrorState.CLOSE_NOW);
+                        setErrorState(ErrorState.CLOSE_NOW, null);
                     }
                     continue;
                 } else if(type != Constants.JK_AJP13_FORWARD_REQUEST) {
@@ -141,20 +141,20 @@ public class AjpAprProcessor extends Abs
                     if (log.isDebugEnabled()) {
                         log.debug("Unexpected message: " + type);
                     }
-                    setErrorState(ErrorState.CLOSE_NOW);
+                    setErrorState(ErrorState.CLOSE_NOW, null);
                     break;
                 }
                 keptAlive = true;
                 request.setStartTime(System.currentTimeMillis());
             } catch (IOException e) {
-                setErrorState(ErrorState.CLOSE_NOW);
+                setErrorState(ErrorState.CLOSE_NOW, e);
                 break;
             } catch (Throwable t) {
                 ExceptionUtils.handleThrowable(t);
                 log.debug(sm.getString("ajpprocessor.header.error"), t);
                 // 400 - Bad Request
                 response.setStatus(400);
-                setErrorState(ErrorState.CLOSE_CLEAN);
+                setErrorState(ErrorState.CLOSE_CLEAN, t);
                 getAdapter().log(request, response, 0);
             }
 
@@ -168,7 +168,7 @@ public class AjpAprProcessor extends Abs
                     log.debug(sm.getString("ajpprocessor.request.prepare"), t);
                     // 500 - Internal Server Error
                     response.setStatus(500);
-                    setErrorState(ErrorState.CLOSE_CLEAN);
+                    setErrorState(ErrorState.CLOSE_CLEAN, t);
                     getAdapter().log(request, response, 0);
                 }
             }
@@ -176,7 +176,7 @@ public class AjpAprProcessor extends Abs
             if (!getErrorState().isError() && !cping && endpoint.isPaused()) {
                 // 503 - Service unavailable
                 response.setStatus(503);
-                setErrorState(ErrorState.CLOSE_CLEAN);
+                setErrorState(ErrorState.CLOSE_CLEAN, null);
                 getAdapter().log(request, response, 0);
             }
             cping = false;
@@ -187,13 +187,13 @@ public class AjpAprProcessor extends Abs
                     rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
                     adapter.service(request, response);
                 } catch (InterruptedIOException e) {
-                    setErrorState(ErrorState.CLOSE_NOW);
+                    setErrorState(ErrorState.CLOSE_NOW, e);
                 } catch (Throwable t) {
                     ExceptionUtils.handleThrowable(t);
                     log.error(sm.getString("ajpprocessor.request.process"), t);
                     // 500 - Internal Server Error
                     response.setStatus(500);
-                    setErrorState(ErrorState.CLOSE_CLEAN);
+                    setErrorState(ErrorState.CLOSE_CLEAN, t);
                     getAdapter().log(request, response, 0);
                 }
             }
@@ -208,7 +208,7 @@ public class AjpAprProcessor extends Abs
                     finish();
                 } catch (Throwable t) {
                     ExceptionUtils.handleThrowable(t);
-                    setErrorState(ErrorState.CLOSE_NOW);
+                    setErrorState(ErrorState.CLOSE_NOW, t);
                 }
             }
 

Modified: tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpNioProcessor.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpNioProcessor.java?rev=1602510&r1=1602509&r2=1602510&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpNioProcessor.java 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpNioProcessor.java Fri 
Jun 13 20:21:32 2014
@@ -118,7 +118,7 @@ public class AjpNioProcessor extends Abs
                     try {
                         output(pongMessageArray, 0, pongMessageArray.length);
                     } catch (IOException e) {
-                        setErrorState(ErrorState.CLOSE_NOW);
+                        setErrorState(ErrorState.CLOSE_NOW, null);
                     }
                     recycle(false);
                     continue;
@@ -128,20 +128,20 @@ public class AjpNioProcessor extends Abs
                     if (log.isDebugEnabled()) {
                         log.debug("Unexpected message: " + type);
                     }
-                    setErrorState(ErrorState.CLOSE_NOW);
+                    setErrorState(ErrorState.CLOSE_NOW, null);
                     recycle(true);
                     break;
                 }
                 request.setStartTime(System.currentTimeMillis());
             } catch (IOException e) {
-                setErrorState(ErrorState.CLOSE_NOW);
+                setErrorState(ErrorState.CLOSE_NOW, e);
                 break;
             } catch (Throwable t) {
                 ExceptionUtils.handleThrowable(t);
                 log.debug(sm.getString("ajpprocessor.header.error"), t);
                 // 400 - Bad Request
                 response.setStatus(400);
-                setErrorState(ErrorState.CLOSE_CLEAN);
+                setErrorState(ErrorState.CLOSE_CLEAN, t);
                 getAdapter().log(request, response, 0);
             }
 
@@ -155,7 +155,7 @@ public class AjpNioProcessor extends Abs
                     log.debug(sm.getString("ajpprocessor.request.prepare"), t);
                     // 500 - Internal Server Error
                     response.setStatus(500);
-                    setErrorState(ErrorState.CLOSE_CLEAN);
+                    setErrorState(ErrorState.CLOSE_CLEAN, t);
                     getAdapter().log(request, response, 0);
                 }
             }
@@ -163,7 +163,7 @@ public class AjpNioProcessor extends Abs
             if (!getErrorState().isError() && !cping && endpoint.isPaused()) {
                 // 503 - Service unavailable
                 response.setStatus(503);
-                setErrorState(ErrorState.CLOSE_CLEAN);
+                setErrorState(ErrorState.CLOSE_CLEAN, null);
                 getAdapter().log(request, response, 0);
             }
             cping = false;
@@ -174,13 +174,13 @@ public class AjpNioProcessor extends Abs
                     rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
                     adapter.service(request, response);
                 } catch (InterruptedIOException e) {
-                    setErrorState(ErrorState.CLOSE_NOW);
+                    setErrorState(ErrorState.CLOSE_NOW, e);
                 } catch (Throwable t) {
                     ExceptionUtils.handleThrowable(t);
                     log.error(sm.getString("ajpprocessor.request.process"), t);
                     // 500 - Internal Server Error
                     response.setStatus(500);
-                    setErrorState(ErrorState.CLOSE_CLEAN);
+                    setErrorState(ErrorState.CLOSE_CLEAN, t);
                     getAdapter().log(request, response, 0);
                 }
             }
@@ -195,7 +195,7 @@ public class AjpNioProcessor extends Abs
                     finish();
                 } catch (Throwable t) {
                     ExceptionUtils.handleThrowable(t);
-                    setErrorState(ErrorState.CLOSE_NOW);
+                    setErrorState(ErrorState.CLOSE_NOW, t);
                 }
             }
 

Modified: tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpProcessor.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpProcessor.java?rev=1602510&r1=1602509&r2=1602510&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpProcessor.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AjpProcessor.java Fri Jun 
13 20:21:32 2014
@@ -135,7 +135,7 @@ public class AjpProcessor extends Abstra
                     try {
                         output.write(pongMessageArray);
                     } catch (IOException e) {
-                        setErrorState(ErrorState.CLOSE_NOW);
+                        setErrorState(ErrorState.CLOSE_NOW, e);
                     }
                     continue;
                 } else if(type != Constants.JK_AJP13_FORWARD_REQUEST) {
@@ -144,19 +144,19 @@ public class AjpProcessor extends Abstra
                     if (log.isDebugEnabled()) {
                         log.debug("Unexpected message: " + type);
                     }
-                    setErrorState(ErrorState.CLOSE_NOW);
+                    setErrorState(ErrorState.CLOSE_NOW, null);
                     break;
                 }
                 request.setStartTime(System.currentTimeMillis());
             } catch (IOException e) {
-                setErrorState(ErrorState.CLOSE_NOW);
+                setErrorState(ErrorState.CLOSE_NOW, e);
                 break;
             } catch (Throwable t) {
                 ExceptionUtils.handleThrowable(t);
                 log.debug(sm.getString("ajpprocessor.header.error"), t);
                 // 400 - Bad Request
                 response.setStatus(400);
-                setErrorState(ErrorState.CLOSE_CLEAN);
+                setErrorState(ErrorState.CLOSE_CLEAN, t);
                 getAdapter().log(request, response, 0);
             }
 
@@ -170,7 +170,7 @@ public class AjpProcessor extends Abstra
                     log.debug(sm.getString("ajpprocessor.request.prepare"), t);
                     // 500 - Internal Server Error
                     response.setStatus(500);
-                    setErrorState(ErrorState.CLOSE_CLEAN);
+                    setErrorState(ErrorState.CLOSE_CLEAN, t);
                     getAdapter().log(request, response, 0);
                 }
             }
@@ -178,7 +178,7 @@ public class AjpProcessor extends Abstra
             if (!getErrorState().isError() && !cping && endpoint.isPaused()) {
                 // 503 - Service unavailable
                 response.setStatus(503);
-                setErrorState(ErrorState.CLOSE_CLEAN);
+                setErrorState(ErrorState.CLOSE_CLEAN, null);
                 getAdapter().log(request, response, 0);
             }
             cping = false;
@@ -189,13 +189,13 @@ public class AjpProcessor extends Abstra
                     rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
                     adapter.service(request, response);
                 } catch (InterruptedIOException e) {
-                    setErrorState(ErrorState.CLOSE_NOW);
+                    setErrorState(ErrorState.CLOSE_NOW, e);
                 } catch (Throwable t) {
                     ExceptionUtils.handleThrowable(t);
                     log.error(sm.getString("ajpprocessor.request.process"), t);
                     // 500 - Internal Server Error
                     response.setStatus(500);
-                    setErrorState(ErrorState.CLOSE_CLEAN);
+                    setErrorState(ErrorState.CLOSE_CLEAN, t);
                     getAdapter().log(request, response, 0);
                 }
             }
@@ -210,7 +210,7 @@ public class AjpProcessor extends Abstra
                     finish();
                 } catch (Throwable t) {
                     ExceptionUtils.handleThrowable(t);
-                    setErrorState(ErrorState.CLOSE_NOW);
+                    setErrorState(ErrorState.CLOSE_NOW, t);
                 }
             }
 

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java?rev=1602510&r1=1602509&r2=1602510&view=diff
==============================================================================
--- 
tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java 
(original)
+++ 
tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java 
Fri Jun 13 20:21:32 2014
@@ -734,7 +734,7 @@ public abstract class AbstractHttp11Proc
             // Unsupported transfer encoding
             // 501 - Unimplemented
             response.setStatus(501);
-            setErrorState(ErrorState.CLOSE_CLEAN);
+            setErrorState(ErrorState.CLOSE_CLEAN, null);
             if (getLog().isDebugEnabled()) {
                 getLog().debug(sm.getString("http11processor.request.prepare") 
+
                           " Unsupported transfer encoding [" + encodingName + 
"]");
@@ -759,7 +759,7 @@ public abstract class AbstractHttp11Proc
             try {
                 getOutputBuffer().endRequest();
             } catch (IOException e) {
-                setErrorState(ErrorState.CLOSE_NOW);
+                setErrorState(ErrorState.CLOSE_NOW, e);
             }
             break;
         }
@@ -774,7 +774,7 @@ public abstract class AbstractHttp11Proc
                 prepareResponse();
                 getOutputBuffer().commit();
             } catch (IOException e) {
-                setErrorState(ErrorState.CLOSE_NOW);
+                setErrorState(ErrorState.CLOSE_NOW, e);
             }
             break;
         }
@@ -790,7 +790,7 @@ public abstract class AbstractHttp11Proc
             try {
                 getOutputBuffer().sendAck();
             } catch (IOException e) {
-                setErrorState(ErrorState.CLOSE_NOW);
+                setErrorState(ErrorState.CLOSE_NOW, e);
             }
             break;
         }
@@ -798,7 +798,7 @@ public abstract class AbstractHttp11Proc
             try {
                 getOutputBuffer().flush();
             } catch (IOException e) {
-                setErrorState(ErrorState.CLOSE_NOW);
+                setErrorState(ErrorState.CLOSE_NOW, e);
                 response.setErrorException(e);
             }
             break;
@@ -810,7 +810,7 @@ public abstract class AbstractHttp11Proc
         case DISABLE_SWALLOW_INPUT: {
             // Do not swallow request input and make sure we are closing the
             // connection
-            setErrorState(ErrorState.CLOSE_CLEAN);
+            setErrorState(ErrorState.CLOSE_CLEAN, null);
             getInputBuffer().setSwallowInput(false);
             break;
         }
@@ -894,7 +894,7 @@ public abstract class AbstractHttp11Proc
         case CLOSE_NOW: {
             // Block further output
             getOutputBuffer().finished = true;
-            setErrorState(ErrorState.CLOSE_NOW);
+            setErrorState(ErrorState.CLOSE_NOW, null);
             break;
         }
         default: {
@@ -989,7 +989,7 @@ public abstract class AbstractHttp11Proc
                 if (endpoint.isPaused()) {
                     // 503 - Service unavailable
                     response.setStatus(503);
-                    setErrorState(ErrorState.CLOSE_CLEAN);
+                    setErrorState(ErrorState.CLOSE_CLEAN, null);
                 } else {
                     // Make sure that connectors that are non-blocking during
                     // header processing (NIO) only set the start time the 
first
@@ -1017,7 +1017,7 @@ public abstract class AbstractHttp11Proc
                     getLog().debug(
                             sm.getString("http11processor.header.parse"), e);
                 }
-                setErrorState(ErrorState.CLOSE_NOW);
+                setErrorState(ErrorState.CLOSE_NOW, e);
                 break;
             } catch (Throwable t) {
                 ExceptionUtils.handleThrowable(t);
@@ -1039,7 +1039,7 @@ public abstract class AbstractHttp11Proc
                 }
                 // 400 - Bad Request
                 response.setStatus(400);
-                setErrorState(ErrorState.CLOSE_CLEAN);
+                setErrorState(ErrorState.CLOSE_CLEAN, t);
                 getAdapter().log(request, response, 0);
             }
 
@@ -1056,7 +1056,7 @@ public abstract class AbstractHttp11Proc
                     }
                     // 500 - Internal Server Error
                     response.setStatus(500);
-                    setErrorState(ErrorState.CLOSE_CLEAN);
+                    setErrorState(ErrorState.CLOSE_CLEAN, t);
                     getAdapter().log(request, response, 0);
                 }
             }
@@ -1082,20 +1082,20 @@ public abstract class AbstractHttp11Proc
                             response.getErrorException() != null ||
                                     (!isAsync() &&
                                     
statusDropsConnection(response.getStatus())))) {
-                        setErrorState(ErrorState.CLOSE_CLEAN);
+                        setErrorState(ErrorState.CLOSE_CLEAN, null);
                     }
                     setCometTimeouts(socketWrapper);
                 } catch (InterruptedIOException e) {
-                    setErrorState(ErrorState.CLOSE_NOW);
+                    setErrorState(ErrorState.CLOSE_NOW, e);
                 } catch (HeadersTooLargeException e) {
                     // The response should not have been committed but check it
                     // anyway to be safe
                     if (response.isCommitted()) {
-                        setErrorState(ErrorState.CLOSE_NOW);
+                        setErrorState(ErrorState.CLOSE_NOW, e);
                     } else {
                         response.reset();
                         response.setStatus(500);
-                        setErrorState(ErrorState.CLOSE_CLEAN);
+                        setErrorState(ErrorState.CLOSE_CLEAN, e);
                         response.setHeader("Connection", "close"); // TODO: 
Remove
                     }
                 } catch (Throwable t) {
@@ -1104,7 +1104,7 @@ public abstract class AbstractHttp11Proc
                             "http11processor.request.process"), t);
                     // 500 - Internal Server Error
                     response.setStatus(500);
-                    setErrorState(ErrorState.CLOSE_CLEAN);
+                    setErrorState(ErrorState.CLOSE_CLEAN, t);
                     getAdapter().log(request, response, 0);
                 }
             }
@@ -1224,7 +1224,7 @@ public abstract class AbstractHttp11Proc
             http11 = false;
             // Send 505; Unsupported HTTP version
             response.setStatus(505);
-            setErrorState(ErrorState.CLOSE_CLEAN);
+            setErrorState(ErrorState.CLOSE_CLEAN, null);
             if (getLog().isDebugEnabled()) {
                 getLog().debug(sm.getString("http11processor.request.prepare")+
                           " Unsupported HTTP version \""+protocolMB+"\"");
@@ -1262,7 +1262,7 @@ public abstract class AbstractHttp11Proc
                 expectation = true;
             } else {
                 response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
-                setErrorState(ErrorState.CLOSE_CLEAN);
+                setErrorState(ErrorState.CLOSE_CLEAN, null);
             }
         }
 
@@ -1356,7 +1356,7 @@ public abstract class AbstractHttp11Proc
         if (http11 && (valueMB == null)) {
             // 400 - Bad request
             response.setStatus(400);
-            setErrorState(ErrorState.CLOSE_CLEAN);
+            setErrorState(ErrorState.CLOSE_CLEAN, null);
             if (getLog().isDebugEnabled()) {
                 getLog().debug(sm.getString("http11processor.request.prepare")+
                           " host header missing");
@@ -1636,7 +1636,7 @@ public abstract class AbstractHttp11Proc
                     // Invalid character
                     // 400 - Bad request
                     response.setStatus(400);
-                    setErrorState(ErrorState.CLOSE_CLEAN);
+                    setErrorState(ErrorState.CLOSE_CLEAN, null);
                     break;
                 }
                 port = port + (charValue * mult);
@@ -1655,14 +1655,14 @@ public abstract class AbstractHttp11Proc
         try {
             rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
             if (!getAdapter().asyncDispatch(request, response, status)) {
-                setErrorState(ErrorState.CLOSE_NOW);
+                setErrorState(ErrorState.CLOSE_NOW, null);
             }
             resetTimeouts();
         } catch (InterruptedIOException e) {
-            setErrorState(ErrorState.CLOSE_NOW);
+            setErrorState(ErrorState.CLOSE_NOW, e);
         } catch (Throwable t) {
             ExceptionUtils.handleThrowable(t);
-            setErrorState(ErrorState.CLOSE_NOW);
+            setErrorState(ErrorState.CLOSE_NOW, t);
             getLog().error(sm.getString("http11processor.request.process"), t);
         } finally {
             if (getErrorState().isError()) {
@@ -1756,14 +1756,14 @@ public abstract class AbstractHttp11Proc
             try {
                 getInputBuffer().endRequest();
             } catch (IOException e) {
-                setErrorState(ErrorState.CLOSE_NOW);
+                setErrorState(ErrorState.CLOSE_NOW, e);
             } catch (Throwable t) {
                 ExceptionUtils.handleThrowable(t);
                 // 500 - Internal Server Error
                 // Can't add a 500 to the access log since that has already 
been
                 // written in the Adapter.service method.
                 response.setStatus(500);
-                setErrorState(ErrorState.CLOSE_NOW);
+                setErrorState(ErrorState.CLOSE_NOW, t);
                 getLog().error(sm.getString("http11processor.request.finish"), 
t);
             }
         }
@@ -1771,10 +1771,10 @@ public abstract class AbstractHttp11Proc
             try {
                 getOutputBuffer().endRequest();
             } catch (IOException e) {
-                setErrorState(ErrorState.CLOSE_NOW);
+                setErrorState(ErrorState.CLOSE_NOW, e);
             } catch (Throwable t) {
                 ExceptionUtils.handleThrowable(t);
-                setErrorState(ErrorState.CLOSE_NOW);
+                setErrorState(ErrorState.CLOSE_NOW, t);
                 
getLog().error(sm.getString("http11processor.response.finish"), t);
             }
         }

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java?rev=1602510&r1=1602509&r2=1602510&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java 
Fri Jun 13 20:21:32 2014
@@ -126,15 +126,15 @@ public class Http11AprProcessor extends 
         try {
             rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
             if (!getAdapter().event(request, response, status)) {
-                setErrorState(ErrorState.CLOSE_NOW);
+                setErrorState(ErrorState.CLOSE_NOW, null);
             }
         } catch (InterruptedIOException e) {
-            setErrorState(ErrorState.CLOSE_NOW);
+            setErrorState(ErrorState.CLOSE_NOW, e);
         } catch (Throwable t) {
             ExceptionUtils.handleThrowable(t);
             // 500 - Internal Server Error
             response.setStatus(500);
-            setErrorState(ErrorState.CLOSE_NOW);
+            setErrorState(ErrorState.CLOSE_NOW, t);
             getAdapter().log(request, response, 0);
             log.error(sm.getString("http11processor.request.process"), t);
         }
@@ -191,7 +191,7 @@ public class Http11AprProcessor extends 
         if (endpoint.isPaused()) {
             // 503 - Service unavailable
             response.setStatus(503);
-            setErrorState(ErrorState.CLOSE_CLEAN);
+            setErrorState(ErrorState.CLOSE_CLEAN, null);
             getAdapter().log(request, response, 0);
         } else {
             return true;
@@ -228,7 +228,7 @@ public class Http11AprProcessor extends 
                         log.debug(sm.getString(
                                 "http11processor.sendfile.error"));
                     }
-                    setErrorState(ErrorState.CLOSE_NOW);
+                    setErrorState(ErrorState.CLOSE_NOW, null);
                 } else {
                     // The sendfile Poller will add the socket to the main
                     // Poller once sendfile processing is complete

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java?rev=1602510&r1=1602509&r2=1602510&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java 
Fri Jun 13 20:21:32 2014
@@ -116,7 +116,7 @@ public class Http11NioProcessor extends 
         try {
             rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
             if (!getAdapter().event(request, response, status)) {
-                setErrorState(ErrorState.CLOSE_NOW);
+                setErrorState(ErrorState.CLOSE_NOW, null);
             }
             if (!getErrorState().isError()) {
                 if (attach != null) {
@@ -139,12 +139,12 @@ public class Http11NioProcessor extends 
                 }
             }
         } catch (InterruptedIOException e) {
-            setErrorState(ErrorState.CLOSE_NOW);
+            setErrorState(ErrorState.CLOSE_NOW, e);
         } catch (Throwable t) {
             ExceptionUtils.handleThrowable(t);
             // 500 - Internal Server Error
             response.setStatus(500);
-            setErrorState(ErrorState.CLOSE_NOW);
+            setErrorState(ErrorState.CLOSE_NOW, t);
             log.error(sm.getString("http11processor.request.process"), t);
             getAdapter().log(request, response, 0);
         }
@@ -233,7 +233,7 @@ public class Http11NioProcessor extends 
         if (endpoint.isPaused()) {
             // 503 - Service unavailable
             response.setStatus(503);
-            setErrorState(ErrorState.CLOSE_CLEAN);
+            setErrorState(ErrorState.CLOSE_CLEAN, null);
             getAdapter().log(request, response, 0);
         } else {
             return true;
@@ -287,7 +287,7 @@ public class Http11NioProcessor extends 
                 if (log.isDebugEnabled()) {
                     log.debug(sm.getString("http11processor.sendfile.error"));
                 }
-                setErrorState(ErrorState.CLOSE_NOW);
+                setErrorState(ErrorState.CLOSE_NOW, null);
             }
             return true;
         }

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/upgrade/AbstractProcessor.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/upgrade/AbstractProcessor.java?rev=1602510&r1=1602509&r2=1602510&view=diff
==============================================================================
--- 
tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/upgrade/AbstractProcessor.java
 (original)
+++ 
tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/upgrade/AbstractProcessor.java
 Fri Jun 13 20:21:32 2014
@@ -161,6 +161,11 @@ public abstract class AbstractProcessor<
     }
 
     @Override
+    public void errorDispatch() {
+        // NO-OP
+    }
+
+    @Override
     public final SocketState asyncPostProcess() {
         return null;
     }

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessor.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessor.java?rev=1602510&r1=1602509&r2=1602510&view=diff
==============================================================================
--- 
tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessor.java
 (original)
+++ 
tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessor.java
 Fri Jun 13 20:21:32 2014
@@ -135,6 +135,11 @@ public abstract class UpgradeProcessor<S
     }
 
     @Override
+    public void errorDispatch() {
+        // NO-OP
+    }
+
+    @Override
     public final SocketState asyncPostProcess() {
         return null;
     }

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java?rev=1602510&r1=1602509&r2=1602510&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java 
Fri Jun 13 20:21:32 2014
@@ -623,7 +623,7 @@ public abstract class AbstractEndpoint<S
 
     // ---------------------------------------------- Request processing 
methods
 
-    protected abstract void processSocketAsync(SocketWrapper<S> socketWrapper,
+    public abstract void processSocketAsync(SocketWrapper<S> socketWrapper,
             SocketStatus socketStatus);
 
 

Modified: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/NioChannel.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/NioChannel.java?rev=1602510&r1=1602509&r2=1602510&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/NioChannel.java 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/NioChannel.java Fri 
Jun 13 20:21:32 2014
@@ -27,6 +27,7 @@ import java.nio.channels.SocketChannel;
 
 import org.apache.tomcat.util.net.NioEndpoint.Poller;
 import org.apache.tomcat.util.net.SecureNioChannel.ApplicationBufferHandler;
+import org.apache.tomcat.util.res.StringManager;
 
 /**
  *
@@ -39,6 +40,9 @@ import org.apache.tomcat.util.net.Secure
  */
 public class NioChannel implements ByteChannel{
 
+    protected static final StringManager sm =
+            StringManager.getManager("org.apache.tomcat.util.net.res");
+
     protected static ByteBuffer emptyBuf = ByteBuffer.allocate(0);
 
     protected SocketChannel sc = null;
@@ -120,6 +124,7 @@ public class NioChannel implements ByteC
      */
     @Override
     public int write(ByteBuffer src) throws IOException {
+        checkInterruptStatus();
         return sc.write(src);
     }
 
@@ -224,4 +229,19 @@ public class NioChannel implements ByteC
     }
 
 
+    /**
+     * This method should be used to check the interrupt status before
+     * attempting a write.
+     *
+     * If a thread has been interrupted and the interrupt has not been cleared
+     * then an attempt to write to the socket will fail. When this happens the
+     * socket is removed from the poller without the socket being selected. 
This
+     * results in a connection limit leak for NIO as the endpoint expects the
+     * socket to be selected even in error conditions.
+     */
+    protected void checkInterruptStatus() throws IOException {
+        if (Thread.interrupted()) {
+            throw new IOException(sm.getString("channel.nio.interrupted"));
+        }
+    }
 }

Modified: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java?rev=1602510&r1=1602509&r2=1602510&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java Fri 
Jun 13 20:21:32 2014
@@ -723,7 +723,7 @@ public class NioEndpoint extends Abstrac
 
 
     @Override
-    protected void processSocketAsync(SocketWrapper<NioChannel> socketWrapper,
+    public void processSocketAsync(SocketWrapper<NioChannel> socketWrapper,
             SocketStatus socketStatus) {
         dispatchForEvent(socketWrapper.getSocket(), socketStatus, true);
     }

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java?rev=1602510&r1=1602509&r2=1602510&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java 
Fri Jun 13 20:21:32 2014
@@ -471,6 +471,7 @@ public class SecureNioChannel extends Ni
      */
     @Override
     public int write(ByteBuffer src) throws IOException {
+        checkInterruptStatus();
         if ( src == this.netOutBuffer ) {
             //we can get here through a recursive call
             //by using the NioBlockingSelector

Modified: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/SocketStatus.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/SocketStatus.java?rev=1602510&r1=1602509&r2=1602510&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/SocketStatus.java 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/SocketStatus.java Fri 
Jun 13 20:21:32 2014
@@ -23,5 +23,5 @@ package org.apache.tomcat.util.net;
  * @author remm
  */
 public enum SocketStatus {
-    OPEN_READ, OPEN_WRITE, STOP, TIMEOUT, DISCONNECT, ERROR
+    OPEN_READ, OPEN_WRITE, STOP, TIMEOUT, DISCONNECT, ERROR, CLOSE_NOW
 }

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/res/LocalStrings.properties
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/res/LocalStrings.properties?rev=1602510&r1=1602509&r2=1602510&view=diff
==============================================================================
--- 
tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/res/LocalStrings.properties
 (original)
+++ 
tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/res/LocalStrings.properties
 Fri Jun 13 20:21:32 2014
@@ -57,3 +57,5 @@ endpoint.apr.pollUnknownEvent=A socket w
 endpoint.apr.remoteport=APR socket [{0}] opened with remote port [{1}]
 endpoint.nio.selectorCloseFail=Failed to close selector when closing the poller
 endpoint.warn.noExector=Failed to process socket [{0}] in state [{1}] because 
the executor had already been shutdown
+
+channel.nio.interrupted=The current thread was interrupted

Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1602510&r1=1602509&r2=1602510&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Fri Jun 13 20:21:32 2014
@@ -106,6 +106,12 @@
   <subsection name="Coyote">
     <changelog>
       <fix>
+        <bug>56518</bug>: When using NIO, do not attempt to write to the socket
+        if the thread is marked interrupted as this will lead to a connection
+        limit leak. This fix was based on analysis of the issue by hanyong.
+        (markt)
+      </fix>
+      <fix>
         <bug>56521</bug>: Re-use the asynchronous write buffer between writes 
to
         reduce allocation and GC overhead. Based on a patch by leonzhx. Also
         make the buffer size configurable and remove copying of data within



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

Reply via email to