Fixed a bug where NioWorker.register() hangs up with high CPU consumption when it failed to open a selector.

This commit is contained in:
Trustin Lee 2008-11-06 11:39:17 +00:00
parent 7f1ff668f7
commit 00ec5be6dd

View File

@ -86,30 +86,39 @@ class NioWorker implements Runnable {
}
void register(NioSocketChannel channel, ChannelFuture future) {
boolean firstChannel = started.compareAndSet(false, true);
boolean firstChannel;
Selector selector;
if (firstChannel) {
boolean success = false;
selectorGuard.writeLock().lock();
try {
this.selector = selector = Selector.open();
success = true;
} catch (IOException e) {
throw new ChannelException(
"Failed to create a selector.", e);
} finally {
selectorGuard.writeLock().unlock();
if (!success) {
started.compareAndSet(true, false);
for (;;) {
firstChannel = started.compareAndSet(false, true);
if (firstChannel) {
boolean success = false;
selectorGuard.writeLock().lock();
try {
this.selector = selector = Selector.open();
success = true;
} catch (IOException e) {
throw new ChannelException(
"Failed to create a selector.", e);
} finally {
selectorGuard.writeLock().unlock();
if (!success) {
started.compareAndSet(true, false);
}
}
break;
} else {
selector = this.selector;
if (selector == null) {
do {
Thread.yield();
selector = this.selector;
} while (selector == null && started.get());
}
if (selector != null) {
break;
}
}
} else {
selector = this.selector;
if (selector == null) {
do {
Thread.yield();
selector = this.selector;
} while (selector == null);
}
}