Author: remm
Date: Fri Apr 27 14:14:22 2018
New Revision: 1830355

URL: http://svn.apache.org/viewvc?rev=1830355&view=rev
Log:
Fix block read/writes state with NIO2, as most often the calling code with a 
blocking operation needs to see the result of the state updates done in the 
completion handler. There's no change in most cases.

Modified:
    tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java
    tomcat/trunk/webapps/docs/changelog.xml

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java?rev=1830355&r1=1830354&r2=1830355&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java Fri Apr 27 
14:14:22 2018
@@ -904,18 +904,22 @@ public class Nio2Endpoint extends Abstra
                         }
                     }
                     if (complete) {
-                        synchronized (state) {
-                            readPending.release();
-                            if (state.block == BlockingMode.BLOCK && 
currentState != CompletionState.INLINE) {
-                                state.state = currentState;
-                                state.notify();
-                            } else {
-                                state.state = currentState;
-                            }
+                        boolean notify = false;
+                        readPending.release();
+                        if (state.block == BlockingMode.BLOCK && currentState 
!= CompletionState.INLINE) {
+                            state.state = currentState;
+                            notify = true;
+                        } else {
+                            state.state = currentState;
                         }
                         if (completion && state.handler != null) {
                             
state.handler.completed(Long.valueOf(state.nBytes), state.attachment);
                         }
+                        if (notify) {
+                            synchronized (state) {
+                                state.notify();
+                            }
+                        }
                     } else {
                         getSocket().read(state.buffers, state.offset, 
state.length,
                                 state.timeout, state.unit, state, this);
@@ -931,14 +935,14 @@ public class Nio2Endpoint extends Abstra
                     ioe = new IOException(exc);
                 }
                 setError(ioe);
-                synchronized (state) {
-                    readPending.release();
-                    if (state.block == BlockingMode.BLOCK) {
-                        state.state = Nio2Endpoint.isInline() ? 
CompletionState.ERROR : CompletionState.DONE;
-                        state.notify();
-                    } else {
-                        state.state = Nio2Endpoint.isInline() ? 
CompletionState.ERROR : CompletionState.DONE;
-                    }
+                boolean notify = false;
+                readPending.release();
+                readPending.release();
+                if (state.block == BlockingMode.BLOCK) {
+                    state.state = Nio2Endpoint.isInline() ? 
CompletionState.ERROR : CompletionState.DONE;
+                    notify = true;
+                } else {
+                    state.state = Nio2Endpoint.isInline() ? 
CompletionState.ERROR : CompletionState.DONE;
                 }
                 if (exc instanceof AsynchronousCloseException) {
                     // If already closed, don't call onError and close again
@@ -947,6 +951,11 @@ public class Nio2Endpoint extends Abstra
                 if (state.handler != null) {
                     state.handler.failed(ioe, state.attachment);
                 }
+                if (notify) {
+                    synchronized (state) {
+                        state.notify();
+                    }
+                }
             }
         }
 
@@ -973,18 +982,22 @@ public class Nio2Endpoint extends Abstra
                         }
                     }
                     if (complete) {
-                        synchronized (state) {
-                            writePending.release();
-                            if (state.block == BlockingMode.BLOCK && 
currentState != CompletionState.INLINE) {
-                                state.state = currentState;
-                                state.notify();
-                            } else {
-                                state.state = currentState;
-                            }
+                        boolean notify = false;
+                        writePending.release();
+                        if (state.block == BlockingMode.BLOCK && currentState 
!= CompletionState.INLINE) {
+                            state.state = currentState;
+                            notify = true;
+                        } else {
+                            state.state = currentState;
                         }
                         if (completion && state.handler != null) {
                             
state.handler.completed(Long.valueOf(state.nBytes), state.attachment);
                         }
+                        if (notify) {
+                            synchronized (state) {
+                                state.notify();
+                            }
+                        }
                     } else {
                         getSocket().write(state.buffers, state.offset, 
state.length,
                                 state.timeout, state.unit, state, this);
@@ -1000,18 +1013,22 @@ public class Nio2Endpoint extends Abstra
                     ioe = new IOException(exc);
                 }
                 setError(ioe);
-                synchronized (state) {
-                    writePending.release();
-                    if (state.block == BlockingMode.BLOCK) {
-                        state.state = Nio2Endpoint.isInline() ? 
CompletionState.ERROR : CompletionState.DONE;
-                        state.notify();
-                    } else {
-                        state.state = Nio2Endpoint.isInline() ? 
CompletionState.ERROR : CompletionState.DONE;
-                    }
+                boolean notify = false;
+                writePending.release();
+                if (state.block == BlockingMode.BLOCK) {
+                    state.state = Nio2Endpoint.isInline() ? 
CompletionState.ERROR : CompletionState.DONE;
+                    notify = true;
+                } else {
+                    state.state = Nio2Endpoint.isInline() ? 
CompletionState.ERROR : CompletionState.DONE;
                 }
                 if (state.handler != null) {
                     state.handler.failed(ioe, state.attachment);
                 }
+                if (notify) {
+                    synchronized (state) {
+                        state.notify();
+                    }
+                }
             }
         }
 
@@ -1024,6 +1041,9 @@ public class Nio2Endpoint extends Abstra
                 handler.failed(ioe, attachment);
                 return CompletionState.ERROR;
             }
+            if (timeout == -1) {
+                timeout = getNio2ReadTimeout();
+            }
             if (block != BlockingMode.NON_BLOCK) {
                 try {
                     if (!readPending.tryAcquire(timeout, unit)) {
@@ -1095,6 +1115,9 @@ public class Nio2Endpoint extends Abstra
                 handler.failed(ioe, attachment);
                 return CompletionState.ERROR;
             }
+            if (timeout == -1) {
+                timeout = getNio2WriteTimeout();
+            }
             if (block != BlockingMode.NON_BLOCK) {
                 try {
                     if (!writePending.tryAcquire(timeout, unit)) {

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1830355&r1=1830354&r2=1830355&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Fri Apr 27 14:14:22 2018
@@ -106,6 +106,9 @@
         browsers) that do not correctly %nn encode URI paths and query strings
         as required by RFC 7230 and RFC 3986. (markt)
       </add>
+      <fix>
+        Fix sync for NIO2 async IO blocking read/writes. (remm)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Jasper">



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

Reply via email to