Set readPending to false when EOF is detected while issue an read

Motivation:

We need to set readPending to false when we detect a EOF while issue a read as otherwise we may not unregister from the Selector / Epoll / KQueue and so keep on receving wakeups.

The important bit is that we may even get a wakeup for a read event but will still will only be able to read 0 bytes from the socket, so we need to be very careful when we clear the readPending. This can happen because we generally using edge-triggered mode for our native transports and because of the nature of edge-triggered we may schedule an read event just to find out there is nothing left to read atm (because we completely drained the socket on the previous read).

Modifications:

Set readPending to false when EOF is detected.

Result:

Fixes [#7255].
This commit is contained in:
Norman Maurer 2017-09-28 08:52:04 +02:00
parent 570d96d8c2
commit e7f02b1dc0
4 changed files with 16 additions and 0 deletions

View File

@ -790,6 +790,10 @@ public abstract class AbstractEpollStreamChannel extends AbstractEpollChannel im
byteBuf.release();
byteBuf = null;
close = allocHandle.lastBytesRead() < 0;
if (close) {
// There is nothing left to read as we received an EOF.
readPending = false;
}
break;
}
allocHandle.incMessagesRead(1);

View File

@ -532,6 +532,10 @@ public abstract class AbstractKQueueStreamChannel extends AbstractKQueueChannel
byteBuf.release();
byteBuf = null;
close = allocHandle.lastBytesRead() < 0;
if (close) {
// There is nothing left to read as we received an EOF.
readPending = false;
}
break;
}
allocHandle.incMessagesRead(1);

View File

@ -126,6 +126,10 @@ public abstract class AbstractNioByteChannel extends AbstractNioChannel {
byteBuf.release();
byteBuf = null;
close = allocHandle.lastBytesRead() < 0;
if (close) {
// There is nothing left to read as we received an EOF.
readPending = false;
}
break;
}

View File

@ -123,6 +123,10 @@ public abstract class AbstractOioByteChannel extends AbstractOioChannel {
byteBuf.release();
byteBuf = null;
close = allocHandle.lastBytesRead() < 0;
if (close) {
// There is nothing left to read as we received an EOF.
readPending = false;
}
}
break;
} else {