Applied the same fix for 'too many open files' to NioDatagramWorker
This commit is contained in:
parent
7f05275305
commit
698f8d54eb
@ -125,6 +125,8 @@ class NioDatagramWorker implements Runnable {
|
|||||||
*/
|
*/
|
||||||
private final Queue<Runnable> writeTaskQueue = new LinkedTransferQueue<Runnable>();
|
private final Queue<Runnable> writeTaskQueue = new LinkedTransferQueue<Runnable>();
|
||||||
|
|
||||||
|
private volatile int cancelledKeys;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sole constructor.
|
* Sole constructor.
|
||||||
*
|
*
|
||||||
@ -250,6 +252,7 @@ class NioDatagramWorker implements Runnable {
|
|||||||
selector.wakeup();
|
selector.wakeup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cancelledKeys = 0;
|
||||||
processRegisterTaskQueue();
|
processRegisterTaskQueue();
|
||||||
processWriteTaskQueue();
|
processWriteTaskQueue();
|
||||||
processSelectedKeys(selector.selectedKeys());
|
processSelectedKeys(selector.selectedKeys());
|
||||||
@ -647,14 +650,37 @@ class NioDatagramWorker implements Runnable {
|
|||||||
// Otherwise DatagramChannel.register() in RegisterTask can be called
|
// Otherwise DatagramChannel.register() in RegisterTask can be called
|
||||||
// after cancel(), but before close(), resulting in the infinite
|
// after cancel(), but before close(), resulting in the infinite
|
||||||
// Selector loop that refuses to shut down due to the dangling keys.
|
// Selector loop that refuses to shut down due to the dangling keys.
|
||||||
|
boolean cancelled = false;
|
||||||
synchronized (channel.interestOpsLock) {
|
synchronized (channel.interestOpsLock) {
|
||||||
SelectionKey key = channel.getDatagramChannel().keyFor(selector);
|
SelectionKey key = channel.getDatagramChannel().keyFor(selector);
|
||||||
if (key != null) {
|
if (key != null) {
|
||||||
key.cancel();
|
key.cancel();
|
||||||
|
cancelled = true;
|
||||||
}
|
}
|
||||||
channel.getDatagramChannel().close();
|
channel.getDatagramChannel().close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cancelled) {
|
||||||
|
int cancelledKeys = ++ worker.cancelledKeys;
|
||||||
|
if (cancelledKeys >= 128) { // FIXME hardcoded value
|
||||||
|
worker.cancelledKeys = 0;
|
||||||
|
// Reclaim the associated file descriptors immediately.
|
||||||
|
// Otherwise the process will experience sudden spike
|
||||||
|
// in the number of open files, with high chance of getting
|
||||||
|
// the 'too many open files' error.
|
||||||
|
if (Thread.currentThread() == worker.thread) {
|
||||||
|
selector.selectNow();
|
||||||
|
if (worker.wakenUp.get()) {
|
||||||
|
selector.wakeup();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (worker.wakenUp.compareAndSet(false, true)) {
|
||||||
|
selector.wakeup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (channel.setClosed()) {
|
if (channel.setClosed()) {
|
||||||
future.setSuccess();
|
future.setSuccess();
|
||||||
if (connected) {
|
if (connected) {
|
||||||
|
Loading…
Reference in New Issue
Block a user