Source:
<code>private boolean scatteringRead(EpollRecvByteAllocatorHandle allocHandle, ByteBuf byteBuf, int datagramSize, int numDatagram) throws IOException { RecyclableArrayList bufferPackets = null; try { int offset = byteBuf.writerIndex(); NativeDatagramPacketArray array = cleanDatagramPacketArray(); for (int i = 0; i < numDatagram; i++, offset += datagramSize) { if (!array.addWritable(byteBuf, offset, datagramSize)) { break; } } allocHandle.attemptedBytesRead(offset - byteBuf.writerIndex()); NativeDatagramPacketArray.NativeDatagramPacket[] packets = array.packets(); int received = socket.recvmmsg(packets, 0, array.count()); if (received == 0) { allocHandle.lastBytesRead(-1); return false; } byteBuf.writerIndex(received * datagramSize); InetSocketAddress local = localAddress(); if (received == 1) { DatagramPacket packet = packets[0].newDatagramPacket(byteBuf, local); allocHandle.lastBytesRead(datagramSize); allocHandle.incMessagesRead(1); pipeline().fireChannelRead(packet); byteBuf = null; return true; } bufferPackets = RecyclableArrayList.newInstance(); for (int i = 0; i < received; i++) { DatagramPacket packet = packets[i].newDatagramPacket(byteBuf.readRetainedSlice(datagramSize), local); bufferPackets.add(packet); } <START> allocHandle.lastBytesRead(datagramSize * received); <END> allocHandle.incMessagesRead(received); for (int i = 0; i < received; i++) { pipeline().fireChannelRead(bufferPackets.set(i, Unpooled.EMPTY_BUFFER)); } bufferPackets.recycle(); bufferPackets = null; return true; } finally { if (byteBuf != null) { byteBuf.release(); } if (bufferPackets != null) { for (int i = 0; i < bufferPackets.size(); i++) { ReferenceCountUtil.release(bufferPackets.get(i)); } bufferPackets.recycle(); } } }</code><technical_language>nit: noticed received * datagramSize line 586, do</technical_language>

Target:
private boolean scatteringRead(EpollRecvByteAllocatorHandle allocHandle, ByteBuf byteBuf, int datagramSize, int numDatagram) throws IOException { RecyclableArrayList bufferPackets = null; try { int offset = byteBuf.writerIndex(); NativeDatagramPacketArray array = cleanDatagramPacketArray(); for (int i = 0; i < numDatagram; i++, offset += datagramSize) { if (!array.addWritable(byteBuf, offset, datagramSize)) { break; } } allocHandle.attemptedBytesRead(offset - byteBuf.writerIndex()); NativeDatagramPacketArray.NativeDatagramPacket[] packets = array.packets(); int received = socket.recvmmsg(packets, 0, array.count()); if (received == 0) { allocHandle.lastBytesRead(-1); return false; } int bytesReceived = received * datagramSize; byteBuf.writerIndex(bytesReceived); InetSocketAddress local = localAddress(); if (received == 1) { DatagramPacket packet = packets[0].newDatagramPacket(byteBuf, local); allocHandle.lastBytesRead(datagramSize); allocHandle.incMessagesRead(1); pipeline().fireChannelRead(packet); byteBuf = null; return true; } bufferPackets = RecyclableArrayList.newInstance(); for (int i = 0; i < received; i++) { DatagramPacket packet = packets[i].newDatagramPacket(byteBuf.readRetainedSlice(datagramSize), local); bufferPackets.add(packet); } allocHandle.lastBytesRead(bytesReceived); allocHandle.incMessagesRead(received); for (int i = 0; i < received; i++) { pipeline().fireChannelRead(bufferPackets.set(i, Unpooled.EMPTY_BUFFER)); } bufferPackets.recycle(); bufferPackets = null; return true; } finally { if (byteBuf != null) { byteBuf.release(); } if (bufferPackets != null) { for (int i = 0; i < bufferPackets.size(); i++) { ReferenceCountUtil.release(bufferPackets.get(i)); } bufferPackets.recycle(); } } }