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