(Nio|Epoll)EventLoop.pendingTasks does not need to dispatch to the EventLoop (#8197)

Motivation:

EventLoop.pendingTasks should be (reasonably) cheap to invoke so it can be used within observability. 

Modifications:

Remove code that dispatch access to the internal taskqueue to the EventLoop when invoked as this is not needed anymore with the current MPSC queues we are using. 

See https://github.com/netty/netty/issues/8196#issuecomment-413653286.

Result:

Fixes https://github.com/netty/netty/issues/8196
This commit is contained in:
Ziyan Mo 2018-08-17 22:28:31 -07:00 committed by Norman Maurer
parent df00539fa2
commit 785473788f
4 changed files with 1 additions and 50 deletions

View File

@ -304,7 +304,7 @@ public abstract class SingleThreadEventExecutor extends AbstractScheduledEventEx
* Return the number of tasks that are pending for processing. * Return the number of tasks that are pending for processing.
* *
* <strong>Be aware that this operation may be expensive as it depends on the internal implementation of the * <strong>Be aware that this operation may be expensive as it depends on the internal implementation of the
* SingleThreadEventExecutor. So use it was care!</strong> * SingleThreadEventExecutor. So use it with care!</strong>
*/ */
public int pendingTasks() { public int pendingTasks() {
return taskQueue.size(); return taskQueue.size();

View File

@ -73,12 +73,6 @@ final class EpollEventLoop extends SingleThreadEventLoop {
return epollWaitNow(); return epollWaitNow();
} }
}; };
private final Callable<Integer> pendingTasksCallable = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return EpollEventLoop.super.pendingTasks();
}
};
private volatile int wakenUp; private volatile int wakenUp;
private volatile int ioRatio = 50; private volatile int ioRatio = 50;
@ -215,17 +209,6 @@ final class EpollEventLoop extends SingleThreadEventLoop {
: PlatformDependent.<Runnable>newMpscQueue(maxPendingTasks); : PlatformDependent.<Runnable>newMpscQueue(maxPendingTasks);
} }
@Override
public int pendingTasks() {
// As we use a MpscQueue we need to ensure pendingTasks() is only executed from within the EventLoop as
// otherwise we may see unexpected behavior (as size() is only allowed to be called by a single consumer).
// See https://github.com/netty/netty/issues/5297
if (inEventLoop()) {
return super.pendingTasks();
} else {
return submit(pendingTasksCallable).syncUninterruptibly().getNow();
}
}
/** /**
* Returns the percentage of the desired amount of time spent for I/O in the event loop. * Returns the percentage of the desired amount of time spent for I/O in the event loop.
*/ */

View File

@ -66,12 +66,6 @@ final class KQueueEventLoop extends SingleThreadEventLoop {
return kqueueWaitNow(); return kqueueWaitNow();
} }
}; };
private final Callable<Integer> pendingTasksCallable = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return KQueueEventLoop.super.pendingTasks();
}
};
private volatile int wakenUp; private volatile int wakenUp;
private volatile int ioRatio = 50; private volatile int ioRatio = 50;
@ -301,14 +295,6 @@ final class KQueueEventLoop extends SingleThreadEventLoop {
: PlatformDependent.<Runnable>newMpscQueue(maxPendingTasks); : PlatformDependent.<Runnable>newMpscQueue(maxPendingTasks);
} }
@Override
public int pendingTasks() {
// As we use a MpscQueue we need to ensure pendingTasks() is only executed from within the EventLoop as
// otherwise we may see unexpected behavior (as size() is only allowed to be called by a single consumer).
// See https://github.com/netty/netty/issues/5297
return inEventLoop() ? super.pendingTasks() : submit(pendingTasksCallable).syncUninterruptibly().getNow();
}
/** /**
* Returns the percentage of the desired amount of time spent for I/O in the event loop. * Returns the percentage of the desired amount of time spent for I/O in the event loop.
*/ */

View File

@ -71,12 +71,6 @@ public final class NioEventLoop extends SingleThreadEventLoop {
return selectNow(); return selectNow();
} }
}; };
private final Callable<Integer> pendingTasksCallable = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return NioEventLoop.super.pendingTasks();
}
};
// Workaround for JDK NIO bug. // Workaround for JDK NIO bug.
// //
@ -259,18 +253,6 @@ public final class NioEventLoop extends SingleThreadEventLoop {
: PlatformDependent.<Runnable>newMpscQueue(maxPendingTasks); : PlatformDependent.<Runnable>newMpscQueue(maxPendingTasks);
} }
@Override
public int pendingTasks() {
// As we use a MpscQueue we need to ensure pendingTasks() is only executed from within the EventLoop as
// otherwise we may see unexpected behavior (as size() is only allowed to be called by a single consumer).
// See https://github.com/netty/netty/issues/5297
if (inEventLoop()) {
return super.pendingTasks();
} else {
return submit(pendingTasksCallable).syncUninterruptibly().getNow();
}
}
/** /**
* Registers an arbitrary {@link SelectableChannel}, not necessarily created by Netty, to the {@link Selector} * Registers an arbitrary {@link SelectableChannel}, not necessarily created by Netty, to the {@link Selector}
* of this event loop. Once the specified {@link SelectableChannel} is registered, the specified {@code task} will * of this event loop. Once the specified {@link SelectableChannel} is registered, the specified {@code task} will