Correctly handle ByteBuf implementations which have no memoryAddress when writing to native transport

Motivation:

Commit 3c4dfed08a introduced a regression in handling buffers that have no memoryAddress.

Modifications:

Fix regression and also add unit tests.

Result:

It's possible again to write buffers without memory address.
This commit is contained in:
Norman Maurer 2017-06-07 17:12:19 +02:00
parent 7922757575
commit 047da11086
3 changed files with 20 additions and 10 deletions

View File

@ -37,7 +37,7 @@ public class DatagramUnicastTest extends AbstractDatagramTest {
private static final byte[] BYTES = {0, 1, 2, 3};
private enum WrapType {
NONE, DUP, SLICE,
NONE, DUP, SLICE, READ_ONLY
}
@Test
@ -189,14 +189,21 @@ public class DatagramUnicastTest extends AbstractDatagramTest {
}
for (int i = 0; i < count; i++) {
if (wrapType == WrapType.DUP) {
switch (wrapType) {
case DUP:
cc.write(new DatagramPacket(buf.retain().duplicate(), addr));
} else if (wrapType == WrapType.SLICE) {
break;
case SLICE:
cc.write(new DatagramPacket(buf.retain().slice(), addr));
} else if (wrapType == WrapType.NONE) {
break;
case READ_ONLY:
cc.write(new DatagramPacket(buf.retain().asReadOnly(), addr));
break;
case NONE:
cc.write(new DatagramPacket(buf.retain(), addr));
} else {
throw new Exception("unknown wrap type: " + wrapType);
break;
default:
throw new Error("unknown wrap type: " + wrapType);
}
}
// release as we used buf.retain() before

View File

@ -47,10 +47,13 @@ public class UnixChannelUtilTest {
private static void testIsBufferCopyNeededForWrite(ByteBufAllocator alloc) {
ByteBuf byteBuf = alloc.directBuffer();
assertFalse(isBufferCopyNeededForWrite(byteBuf));
assertTrue(isBufferCopyNeededForWrite(byteBuf.asReadOnly()));
assertTrue(byteBuf.release());
byteBuf = alloc.heapBuffer();
assertTrue(isBufferCopyNeededForWrite(byteBuf));
assertTrue(isBufferCopyNeededForWrite(byteBuf.asReadOnly()));
assertTrue(byteBuf.release());
assertCompositeByteBufIsBufferCopyNeededForWrite(alloc, 2, 0, false);

View File

@ -29,6 +29,6 @@ public final class UnixChannelUtil {
* (We check this because otherwise we need to make it a new direct buffer.)
*/
public static boolean isBufferCopyNeededForWrite(ByteBuf byteBuf) {
return !(byteBuf.hasMemoryAddress() || byteBuf.isDirect() && byteBuf.nioBufferCount() <= IOV_MAX);
return !byteBuf.hasMemoryAddress() || !byteBuf.isDirect() || byteBuf.nioBufferCount() > IOV_MAX;
}
}