Tiny bit of optimization in event loop

This commit is contained in:
Trustin Lee 2012-05-24 21:04:12 -07:00
parent 02144f70e1
commit 25599018f2
2 changed files with 30 additions and 17 deletions

View File

@ -106,8 +106,9 @@ public abstract class SingleThreadEventLoop extends AbstractExecutorService impl
assert inEventLoop();
Runnable task = taskQueue.poll();
if (task == null) {
fetchScheduledTasks();
task = taskQueue.poll();
if (fetchScheduledTasks()) {
task = taskQueue.poll();
}
}
return task;
}
@ -125,12 +126,24 @@ public abstract class SingleThreadEventLoop extends AbstractExecutorService impl
protected Runnable peekTask() {
assert inEventLoop();
return taskQueue.peek();
Runnable task = taskQueue.peek();
if (task == null) {
if (fetchScheduledTasks()) {
task = taskQueue.peek();
}
}
return task;
}
protected boolean hasTasks() {
assert inEventLoop();
return !taskQueue.isEmpty();
boolean empty = taskQueue.isEmpty();
if (empty) {
if (fetchScheduledTasks()) {
empty = taskQueue.isEmpty();
}
}
return !empty;
}
protected void addTask(Runnable task) {
@ -353,9 +366,9 @@ public abstract class SingleThreadEventLoop extends AbstractExecutorService impl
return task;
}
private void fetchScheduledTasks() {
private boolean fetchScheduledTasks() {
if (scheduledTasks.isEmpty()) {
return;
return false;
}
long nanoTime = nanoTime();
@ -369,6 +382,7 @@ public abstract class SingleThreadEventLoop extends AbstractExecutorService impl
}
if (nanoTime - lastCheckTimeNanos >= SCHEDULE_CHECK_INTERVAL) {
boolean added = false;
for (;;) {
ScheduledFutureTask<?> task = scheduledTasks.poll();
if (task == null) {
@ -380,10 +394,14 @@ public abstract class SingleThreadEventLoop extends AbstractExecutorService impl
task.cancel(false);
} else {
taskQueue.add(task);
added = true;
}
}
}
return added;
}
return false;
}
private void cancelScheduledTasks() {

View File

@ -163,14 +163,15 @@ final class SingleThreadSelectorEventLoop extends SingleThreadEventLoop {
}
private void processSelectedKeys() {
for (Iterator<SelectionKey> i = selector.selectedKeys().iterator(); i.hasNext();) {
Iterator<SelectionKey> i;
for (i = selector.selectedKeys().iterator(); i.hasNext();) {
final SelectionKey k = i.next();
i.remove();
final Channel ch = (Channel) k.attachment();
final Unsafe unsafe = ch.unsafe();
boolean removeKey = true;
try {
int readyOps = k.readyOps();
if ((readyOps & SelectionKey.OP_READ) != 0 || readyOps == 0) {
if ((readyOps & (SelectionKey.OP_READ | SelectionKey.OP_ACCEPT)) != 0 || readyOps == 0) {
unsafe.read();
if (!ch.isOpen()) {
// Connection already closed - no need to handle write.
@ -180,22 +181,16 @@ final class SingleThreadSelectorEventLoop extends SingleThreadEventLoop {
if ((readyOps & SelectionKey.OP_WRITE) != 0) {
unsafe.flushForcibly();
}
if ((readyOps & SelectionKey.OP_ACCEPT) != 0) {
unsafe.read();
}
if ((readyOps & SelectionKey.OP_CONNECT) != 0) {
unsafe.finishConnect();
}
} catch (CancelledKeyException ignored) {
unsafe.close(unsafe.voidFuture());
} finally {
if (removeKey) {
i.remove();
}
}
if (cleanUpCancelledKeys()) {
break; // break the loop to avoid ConcurrentModificationException
// Create the iterator again to avoid ConcurrentModificationException
i = selector.selectedKeys().iterator();
}
}
}