NIO autoReadClear should also clear the SelectionKey
Motivation:
Prior to 5b48fc284e
setting readPending to false when autoReadClear was called was enough because when/if the EventLoop woke up with a read event we would first check if readPending was true and if it is not, we would return early. Now that readPending will only be set in the EventLoop it is not necessary to check readPending at the start of the read methods, and we should instead remove the OP_READ from the SelectionKey when we also set readPending to false.
Modifications:
- autoReadCleared should call AbstractNioUnsafe.removeReadOp
Result:
NIO is now consistent with EPOLL and removes the READ operation on the selector when autoRead is cleared.
This commit is contained in:
parent
562d8d2200
commit
0bc93dda08
@ -65,7 +65,7 @@ public abstract class AbstractNioChannel extends AbstractChannel {
|
|||||||
private final Runnable clearReadPendingRunnable = new Runnable() {
|
private final Runnable clearReadPendingRunnable = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
readPending = false;
|
clearReadPending0();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -149,17 +149,17 @@ public abstract class AbstractNioChannel extends AbstractChannel {
|
|||||||
if (isRegistered()) {
|
if (isRegistered()) {
|
||||||
EventLoop eventLoop = eventLoop();
|
EventLoop eventLoop = eventLoop();
|
||||||
if (eventLoop.inEventLoop()) {
|
if (eventLoop.inEventLoop()) {
|
||||||
this.readPending = readPending;
|
setReadPending0(readPending);
|
||||||
} else {
|
} else {
|
||||||
eventLoop.execute(new OneTimeTask() {
|
eventLoop.execute(new OneTimeTask() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
AbstractNioChannel.this.readPending = readPending;
|
setReadPending0(readPending);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.readPending = readPending;
|
setReadPending0(readPending);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,16 +170,28 @@ public abstract class AbstractNioChannel extends AbstractChannel {
|
|||||||
if (isRegistered()) {
|
if (isRegistered()) {
|
||||||
EventLoop eventLoop = eventLoop();
|
EventLoop eventLoop = eventLoop();
|
||||||
if (eventLoop.inEventLoop()) {
|
if (eventLoop.inEventLoop()) {
|
||||||
readPending = false;
|
clearReadPending0();
|
||||||
} else {
|
} else {
|
||||||
eventLoop.execute(clearReadPendingRunnable);
|
eventLoop.execute(clearReadPendingRunnable);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Best effort if we are not registered yet clear readPending. This happens during channel initialization.
|
// Best effort if we are not registered yet clear readPending. This happens during channel initialization.
|
||||||
readPending = false;
|
clearReadPending0();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setReadPending0(boolean readPending) {
|
||||||
|
this.readPending = readPending;
|
||||||
|
if (!readPending) {
|
||||||
|
((AbstractNioUnsafe) unsafe()).removeReadOp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearReadPending0() {
|
||||||
|
readPending = false;
|
||||||
|
((AbstractNioUnsafe) unsafe()).removeReadOp();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return {@code true} if the input of this {@link Channel} is shutdown
|
* Return {@code true} if the input of this {@link Channel} is shutdown
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user