Fix a race which could lead to an exception on windows when try to release resources. See #395

This commit is contained in:
norman 2012-09-03 14:37:55 +02:00
parent 1ac9930e39
commit 378ea8e475

View File

@ -91,6 +91,8 @@ abstract class AbstractNioWorker implements Worker {
*/ */
volatile Selector selector; volatile Selector selector;
private boolean isShutdown;
/** /**
* Boolean that controls determines if a blocked Selector.select should * Boolean that controls determines if a blocked Selector.select should
* break out of its selection process. In our case we use a timeone for * break out of its selection process. In our case we use a timeone for
@ -378,6 +380,7 @@ abstract class AbstractNioWorker implements Worker {
} finally { } finally {
this.selector = null; this.selector = null;
} }
isShutdown = true;
break; break;
} else { } else {
shutdown = false; shutdown = false;
@ -424,12 +427,22 @@ abstract class AbstractNioWorker implements Worker {
if (!alwaysAsync && Thread.currentThread() == thread) { if (!alwaysAsync && Thread.currentThread() == thread) {
task.run(); task.run();
} else { } else {
synchronized (startStopLock) { eventQueue.offer(task);
start();
boolean added = eventQueue.offer(task);
assert added; synchronized (startStopLock) {
if (added) { // check if the selector was shutdown already. If so execute all
// submitted tasks in the calling thread
if (isShutdown) {
// execute everything in the event queue as the
for (;;) {
Runnable r = eventQueue.poll();
if (r == null) {
break;
}
r.run();
}
} else {
start();
if (wakenUp.compareAndSet(false, true)) { if (wakenUp.compareAndSet(false, true)) {
// wake up the selector to speed things // wake up the selector to speed things
Selector selector = this.selector; Selector selector = this.selector;
@ -437,10 +450,8 @@ abstract class AbstractNioWorker implements Worker {
selector.wakeup(); selector.wakeup();
} }
} }
} }
} }
} }
} }