From d6ec44c871e8598a62a2a403949fbc28d52898bc Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Fri, 18 Apr 2014 20:34:37 +0200 Subject: [PATCH] Fix buffer leak in EpollDatagramChannel Motivation: EpollDatagramChannel produced buffer leaks when tried to read from the channel and nothing was ready to be read. Modifications: Correctly release buffer if nothing was read Result: No buffer leak --- .../channel/epoll/EpollDatagramChannel.java | 40 +++++++------------ 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/transport-native-epoll/src/main/java/io/netty/channel/epoll/EpollDatagramChannel.java b/transport-native-epoll/src/main/java/io/netty/channel/epoll/EpollDatagramChannel.java index 9774d816d4..d7cb9f1cb9 100644 --- a/transport-native-epoll/src/main/java/io/netty/channel/epoll/EpollDatagramChannel.java +++ b/transport-native-epoll/src/main/java/io/netty/channel/epoll/EpollDatagramChannel.java @@ -376,12 +376,11 @@ public final class EpollDatagramChannel extends AbstractEpollChannel implements assert eventLoop().inEventLoop(); final ChannelPipeline pipeline = pipeline(); - Throwable exception = null; try { - try { - for (;;) { - boolean free = true; - ByteBuf data = allocHandle.allocate(config.getAllocator()); + for (;;) { + ByteBuf data = null; + try { + data = allocHandle.allocate(config.getAllocator()); int writerIndex = data.writerIndex(); DatagramSocketAddress remoteAddress; if (data.hasMemoryAddress()) { @@ -401,28 +400,19 @@ public final class EpollDatagramChannel extends AbstractEpollChannel implements int readBytes = remoteAddress.receivedAmount; data.writerIndex(data.writerIndex() + readBytes); allocHandle.record(readBytes); - try { - readPending = false; - pipeline.fireChannelRead( - new DatagramPacket(data, (InetSocketAddress) localAddress(), remoteAddress)); - free = false; - } catch (Throwable t) { - // keep on reading as we use epoll ET and need to consume everything from the socket - pipeline.fireChannelReadComplete(); - pipeline.fireExceptionCaught(t); - } finally { - if (free) { - data.release(); - } + readPending = false; + pipeline.fireChannelRead( + new DatagramPacket(data, (InetSocketAddress) localAddress(), remoteAddress)); + data = null; + } catch (Throwable t) { + // keep on reading as we use epoll ET and need to consume everything from the socket + pipeline.fireChannelReadComplete(); + pipeline.fireExceptionCaught(t); + } finally { + if (data != null) { + data.release(); } } - } catch (Throwable t) { - exception = t; - } - pipeline.fireChannelReadComplete(); - - if (exception != null) { - pipeline.fireExceptionCaught(exception); } } finally { // Check if there is a readPending which was not processed yet.