Make sure AbstractNioWorker gets started if needed

This commit is contained in:
norman 2012-03-07 15:37:33 +01:00
parent 62028f0042
commit e207af30a3

View File

@ -127,13 +127,28 @@ abstract class AbstractNioWorker implements Worker {
void register(AbstractNioChannel<?> channel, ChannelFuture future) { void register(AbstractNioChannel<?> channel, ChannelFuture future) {
Runnable registerTask = createRegisterTask(channel, future); Runnable registerTask = createRegisterTask(channel, future);
Selector selector; Selector selector = start();
boolean offered = registerTaskQueue.offer(registerTask);
assert offered;
if (wakenUp.compareAndSet(false, true)) {
selector.wakeup();
}
}
/**
* Start the {@link AbstractNioWorker} and return the {@link Selector} that will be used for the {@link AbstractNioChannel}'s when they get registered
*
* @return selector
*/
private Selector start() {
synchronized (startStopLock) { synchronized (startStopLock) {
if (!started) { if (!started) {
// Open a selector if this worker didn't start yet. // Open a selector if this worker didn't start yet.
try { try {
this.selector = selector = Selector.open(); this.selector = Selector.open();
} catch (Throwable t) { } catch (Throwable t) {
throw new ChannelException("Failed to create a selector.", t); throw new ChannelException("Failed to create a selector.", t);
} }
@ -151,27 +166,18 @@ abstract class AbstractNioWorker implements Worker {
} catch (Throwable t) { } catch (Throwable t) {
logger.warn("Failed to close a selector.", t); logger.warn("Failed to close a selector.", t);
} }
this.selector = selector = null; this.selector = null;
// The method will return to the caller at this point. // The method will return to the caller at this point.
} }
} }
} else {
// Use the existing selector if this worker has been started.
selector = this.selector;
} }
assert selector != null && selector.isOpen(); assert selector != null && selector.isOpen();
started = true; started = true;
boolean offered = registerTaskQueue.offer(registerTask);
assert offered;
} }
return selector;
if (wakenUp.compareAndSet(false, true)) {
selector.wakeup();
} }
}
@Override @Override
public void run() { public void run() {
@ -281,6 +287,7 @@ abstract class AbstractNioWorker implements Worker {
@Override @Override
public void executeInIoThread(Runnable task) { public void executeInIoThread(Runnable task) {
start();
if (Thread.currentThread() == thread) { if (Thread.currentThread() == thread) {
task.run(); task.run();
} else { } else {
@ -296,7 +303,6 @@ abstract class AbstractNioWorker implements Worker {
} }
} }
} }
private void processRegisterTaskQueue() throws IOException { private void processRegisterTaskQueue() throws IOException {