Tiny bit of optimization in event loop
This commit is contained in:
parent
02144f70e1
commit
25599018f2
@ -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() {
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user