[#943] Fix CanceledKeyException which can happen on frequently deregister/register while using the NIO Transport
This commit is contained in:
parent
895bce6cd5
commit
f136eafd5e
@ -27,6 +27,7 @@ import java.io.IOException;
|
|||||||
import java.net.ConnectException;
|
import java.net.ConnectException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
|
import java.nio.channels.CancelledKeyException;
|
||||||
import java.nio.channels.SelectableChannel;
|
import java.nio.channels.SelectableChannel;
|
||||||
import java.nio.channels.SelectionKey;
|
import java.nio.channels.SelectionKey;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
@ -250,8 +251,24 @@ public abstract class AbstractNioChannel extends AbstractChannel {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Runnable doRegister() throws Exception {
|
protected Runnable doRegister() throws Exception {
|
||||||
|
boolean selected = false;
|
||||||
|
for (;;) {
|
||||||
|
try {
|
||||||
selectionKey = javaChannel().register(eventLoop().selector, 0, this);
|
selectionKey = javaChannel().register(eventLoop().selector, 0, this);
|
||||||
return null;
|
return null;
|
||||||
|
} catch (CancelledKeyException e) {
|
||||||
|
if (!selected) {
|
||||||
|
// Force the Selector to select now as the "canceled" SelectionKey may still be
|
||||||
|
// cached and not removed because no Select.select(..) operation was called yet.
|
||||||
|
eventLoop().selectNow();
|
||||||
|
selected = true;
|
||||||
|
} else {
|
||||||
|
// We forced a select operation on the selector before but the SelectionKey is still cached
|
||||||
|
// for whatever reason. JDK bug ?
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -519,4 +519,15 @@ public final class NioEventLoop extends SingleThreadEventLoop {
|
|||||||
selector.wakeup();
|
selector.wakeup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void selectNow() throws IOException {
|
||||||
|
try {
|
||||||
|
selector.selectNow();
|
||||||
|
} finally {
|
||||||
|
// restore wakup state if needed
|
||||||
|
if (wakenUp.get()) {
|
||||||
|
selector.wakeup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user