Skip to content

Commit

Permalink
[UNDERTOW-1842] At AbstractFramedStreamSinkChannel.flushComplete(), r…
Browse files Browse the repository at this point in the history
…equeue the final frame if we still have a body to be written
  • Loading branch information
fl4via authored and gaol committed Jul 1, 2021
1 parent e6f7dc5 commit 33e5e59
Showing 1 changed file with 19 additions and 15 deletions.
Expand Up @@ -612,17 +612,29 @@ public ByteBuffer getBuffer() {
final void flushComplete() throws IOException {
synchronized (lock) {
try {
boolean resetReadyForFlush = true;
bufferFull = false;
int remaining = header.getRemainingInBuffer();
boolean finalFrame = finalFrameQueued;
boolean channelClosed = finalFrame && remaining == 0 && !header.isAnotherFrameRequired();
if (remaining > 0) {
// We still have a body, but since we just flushed, we transfer it to the write buffer.
// This works as long as you call write() again or if finalFrame is true
//TODO: this code may not work if the channel has frame level compression and flow control
//we don't have an implementation that needs this yet so it is ok for now
body.getBuffer().limit(body.getBuffer().limit() + remaining);
body.getBuffer().compact();
writeBuffer = body;
body = null;
state &= ~STATE_PRE_WRITE_CALLED;
if (finalFrame) {
//we clear the final frame flag, as it could not actually be written out
//note that we don't attempt to requeue, as whatever stopped it from being written will likely still
//be an issue
// we clear the final frame flag, as it could not actually be written out
this.finalFrameQueued = false;
// setting readyForFlush will prevent the final frame to be requeued by write listener, so mark
// it as false; and do not reset it to false later on
// (queueFinalFrame() will set readyForFlush to true and will do so iff readyForFlush is false)
resetReadyForFlush = readyForFlush = false;
queueFinalFrame();
}
} else if (header.isAnotherFrameRequired()) {
this.finalFrameQueued = false;
Expand All @@ -643,25 +655,17 @@ final void flushComplete() throws IOException {
body = null;
state &= ~STATE_PRE_WRITE_CALLED;
}
} else if (body != null) {
// We still have a body, but since we just flushed, we transfer it to the write buffer.
// This works as long as you call write() again

//TODO: this code may not work if the channel has frame level compression and flow control
//we don't have an implementation that needs this yet so it is ok for now

body.getBuffer().compact();
writeBuffer = body;
body = null;
state &= ~STATE_PRE_WRITE_CALLED;
}

if (header.getByteBuffer() != null) {
header.getByteBuffer().close();
}
header = null;

readyForFlush = false;
if (resetReadyForFlush) {
readyForFlush = false;
}

if (isWriteResumed() && !channelClosed) {
wakeupWrites();
} else if (isWriteResumed()) {
Expand Down

0 comments on commit 33e5e59

Please sign in to comment.