[#1707] More efficient implementation of ChannelHandlerContext.writeAndFlush(..)

This commit is contained in:
Norman Maurer 2013-08-07 20:15:10 +02:00
parent 5b6e762bf4
commit 5ef30b6d8b

View File

@ -640,7 +640,7 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
buffer.incrementPendingOutboundBytes(size);
}
}
executor.execute(WriteTask.newInstance(next, msg, size, promise));
executor.execute(WriteTask.newInstance(next, msg, size, false, promise));
}
return promise;
@ -686,9 +686,29 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
@Override
public ChannelFuture writeAndFlush(Object msg, ChannelPromise promise) {
ChannelFuture future = write(msg, promise);
flush();
return future;
if (msg == null) {
throw new NullPointerException("msg");
}
validatePromise(promise, true);
final DefaultChannelHandlerContext next = findContextOutbound();
EventExecutor executor = next.executor();
if (executor.inEventLoop()) {
next.invokeWrite(msg, promise);
next.invokeFlush();
} else {
final int size = channel.estimatorHandle().size(msg);
if (size > 0) {
ChannelOutboundBuffer buffer = channel.unsafe().outboundBuffer();
// Check for null as it may be set to null if the channel is closed already
if (buffer != null) {
buffer.incrementPendingOutboundBytes(size);
}
}
executor.execute(WriteTask.newInstance(next, msg, size, true, promise));
}
return promise;
}
@Override
@ -831,6 +851,7 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
private Object msg;
private ChannelPromise promise;
private int size;
private boolean flush;
private static final Recycler<WriteTask> RECYCLER = new Recycler<WriteTask>() {
@Override
@ -840,12 +861,13 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
};
private static WriteTask newInstance(
DefaultChannelHandlerContext ctx, Object msg, int size, ChannelPromise promise) {
DefaultChannelHandlerContext ctx, Object msg, int size, boolean flush, ChannelPromise promise) {
WriteTask task = RECYCLER.get();
task.ctx = ctx;
task.msg = msg;
task.promise = promise;
task.size = size;
task.flush = flush;
return task;
}
@ -866,6 +888,9 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
}
}
ctx.invokeWrite(msg, promise);
if (flush) {
ctx.invokeFlush();
}
} finally {
// Set to null so the GC can collect them directly
ctx = null;