You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2018/11/26 14:24:45 UTC
svn commit: r1847474 - /tomcat/trunk/java/org/apache/coyote/http2/Stream.java
Author: markt
Date: Mon Nov 26 14:24:45 2018
New Revision: 1847474
URL: http://svn.apache.org/viewvc?rev=1847474&view=rev
Log:
Fix (hopefully) intermittent HTTP/2 test failures with async I/O.
Modified:
tomcat/trunk/java/org/apache/coyote/http2/Stream.java
Modified: tomcat/trunk/java/org/apache/coyote/http2/Stream.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/Stream.java?rev=1847474&r1=1847473&r2=1847474&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/Stream.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http2/Stream.java Mon Nov 26 14:24:45 2018
@@ -717,6 +717,10 @@ class Stream extends AbstractStream impl
private final ByteBuffer buffer = ByteBuffer.allocate(8 * 1024);
private final WriteBuffer writeBuffer = new WriteBuffer(32 * 1024);
+ // Flag that indicates that data was left over on a previous
+ // non-blocking write. Once set, this flag stays set until all the data
+ // has been written.
+ private boolean dataLeft;
private volatile long written = 0;
private int streamReservation = 0;
private volatile boolean closed = false;
@@ -747,6 +751,7 @@ class Stream extends AbstractStream impl
// is full
if (flush(true, coyoteResponse.getWriteListener() == null)) {
writeBuffer.add(chunk);
+ dataLeft = true;
break;
}
}
@@ -767,17 +772,20 @@ class Stream extends AbstractStream impl
* Too many calls and the end of stream message is sent too soon and
* trailer headers are not sent.
*/
- boolean dataLeft = buffer.position() > 0;
+ boolean dataInBuffer = buffer.position() > 0;
boolean flushed = false;
- if (dataLeft) {
- dataLeft = flush(false, block);
+ if (dataInBuffer) {
+ dataInBuffer = flush(false, block);
flushed = true;
}
- if (!dataLeft) {
+ if (!dataInBuffer) {
if (writeBuffer.isEmpty()) {
- if (!flushed) {
+ // Both buffer and writeBuffer are empty.
+ if (flushed) {
+ dataLeft = false;
+ } else {
dataLeft = flush(false, block);
}
} else {
@@ -811,10 +819,10 @@ class Stream extends AbstractStream impl
if (streamReservation == 0) {
streamReservation = reserveWindowSize(left, block);
if (streamReservation == 0) {
- // Must be non-blocking. Unwritten non-blocking data
- // must put in writeBuffer else isReady() logic breaks
- writeBuffer.add(buffer);
- buffer.clear();
+ // Must be non-blocking.
+ // Note: Can't add to the writeBuffer here as the write
+ // may originate from the writeBuffer.
+ buffer.compact();
return true;
}
}
@@ -822,10 +830,10 @@ class Stream extends AbstractStream impl
int connectionReservation =
handler.reserveWindowSize(Stream.this, streamReservation, block);
if (connectionReservation == 0) {
- // Must be non-blocking. Unwritten non-blocking data
- // must put in writeBuffer else isReady() logic breaks
- writeBuffer.add(buffer);
- buffer.clear();
+ // Must be non-blocking.
+ // Note: Can't add to the writeBuffer here as the write
+ // may originate from the writeBuffer.
+ buffer.compact();
return true;
}
// Do the write
@@ -841,7 +849,7 @@ class Stream extends AbstractStream impl
}
final synchronized boolean isReady() {
- if (getWindowSize() > 0 && handler.getWindowSize() > 0 && writeBuffer.isEmpty()) {
+ if (getWindowSize() > 0 && handler.getWindowSize() > 0 && !dataLeft) {
return true;
} else {
return false;
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org