From b627824b186212ce09e3ad81c2dbd1a6ac64e10a Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Tue, 17 Jun 2014 09:26:04 +0200 Subject: [PATCH] [#2577] ChannelOutboundBuffer.addFlush() unnecessary loop through all entries on multiple calls Motivation: If ChannelOutboundBuffer.addFlush() is called multiple times and flushed != unflushed it will still loop through all entries that are not flushed yet even if it is not needed anymore as these were marked uncancellable before. Modifications: Check if new messages were added since addFlush() was called and only if this was the case loop through all entries and try to mark the uncancellable. Result: Less overhead when ChannelOuboundBuffer.addFlush() is called multiple times without new messages been added. --- .../netty/channel/ChannelOutboundBuffer.java | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java b/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java index 3d1b7a59ff..50e745dc67 100644 --- a/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java +++ b/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java @@ -173,18 +173,24 @@ public final class ChannelOutboundBuffer { } void addFlush() { - unflushed = tail; + // There is no need to process all entries if there was already a flush before and no new messages + // where added in the meantime. + // + // See https://github.com/netty/netty/issues/2577 + if (unflushed != tail) { + unflushed = tail; - final int mask = buffer.length - 1; - int i = flushed; - while (i != unflushed && buffer[i].msg != null) { - Entry entry = buffer[i]; - if (!entry.promise.setUncancellable()) { - // Was cancelled so make sure we free up memory and notify about the freed bytes - int pending = entry.cancel(); - decrementPendingOutboundBytes(pending); + final int mask = buffer.length - 1; + int i = flushed; + while (i != unflushed && buffer[i].msg != null) { + Entry entry = buffer[i]; + if (!entry.promise.setUncancellable()) { + // Was cancelled so make sure we free up memory and notify about the freed bytes + int pending = entry.cancel(); + decrementPendingOutboundBytes(pending); + } + i = i + 1 & mask; } - i = i + 1 & mask; } }