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
This commit is contained in:
Norman Maurer 2014-04-18 20:34:37 +02:00
parent b13953fd45
commit 886829d7e0

View File

@ -371,12 +371,11 @@ public final class EpollDatagramChannel extends AbstractEpollChannel implements
assert eventLoop().inEventLoop(); assert eventLoop().inEventLoop();
final ChannelPipeline pipeline = pipeline(); final ChannelPipeline pipeline = pipeline();
Throwable exception = null;
try { try {
try { for (;;) {
for (;;) { ByteBuf data = null;
boolean free = true; try {
ByteBuf data = allocHandle.allocate(config.getAllocator()); data = allocHandle.allocate(config.getAllocator());
int writerIndex = data.writerIndex(); int writerIndex = data.writerIndex();
DatagramSocketAddress remoteAddress; DatagramSocketAddress remoteAddress;
if (data.hasMemoryAddress()) { if (data.hasMemoryAddress()) {
@ -396,28 +395,19 @@ public final class EpollDatagramChannel extends AbstractEpollChannel implements
int readBytes = remoteAddress.receivedAmount; int readBytes = remoteAddress.receivedAmount;
data.writerIndex(data.writerIndex() + readBytes); data.writerIndex(data.writerIndex() + readBytes);
allocHandle.record(readBytes); allocHandle.record(readBytes);
try { readPending = false;
readPending = false; pipeline.fireChannelRead(
pipeline.fireChannelRead( new DatagramPacket(data, (InetSocketAddress) localAddress(), remoteAddress));
new DatagramPacket(data, (InetSocketAddress) localAddress(), remoteAddress)); data = null;
free = false; } catch (Throwable t) {
} catch (Throwable t) { // keep on reading as we use epoll ET and need to consume everything from the socket
// keep on reading as we use epoll ET and need to consume everything from the socket pipeline.fireChannelReadComplete();
pipeline.fireChannelReadComplete(); pipeline.fireExceptionCaught(t);
pipeline.fireExceptionCaught(t); } finally {
} finally { if (data != null) {
if (free) { data.release();
data.release();
}
} }
} }
} catch (Throwable t) {
exception = t;
}
pipeline.fireChannelReadComplete();
if (exception != null) {
pipeline.fireExceptionCaught(exception);
} }
} finally { } finally {
// Check if there is a readPending which was not processed yet. // Check if there is a readPending which was not processed yet.