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

View File

@ -47,10 +47,13 @@ public class UnixChannelUtilTest {
private static void testIsBufferCopyNeededForWrite(ByteBufAllocator alloc) { private static void testIsBufferCopyNeededForWrite(ByteBufAllocator alloc) {
ByteBuf byteBuf = alloc.directBuffer(); ByteBuf byteBuf = alloc.directBuffer();
assertFalse(isBufferCopyNeededForWrite(byteBuf)); assertFalse(isBufferCopyNeededForWrite(byteBuf));
assertTrue(isBufferCopyNeededForWrite(byteBuf.asReadOnly()));
assertTrue(byteBuf.release()); assertTrue(byteBuf.release());
byteBuf = alloc.heapBuffer(); byteBuf = alloc.heapBuffer();
assertTrue(isBufferCopyNeededForWrite(byteBuf)); assertTrue(isBufferCopyNeededForWrite(byteBuf));
assertTrue(isBufferCopyNeededForWrite(byteBuf.asReadOnly()));
assertTrue(byteBuf.release()); assertTrue(byteBuf.release());
assertCompositeByteBufIsBufferCopyNeededForWrite(alloc, 2, 0, false); 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.) * (We check this because otherwise we need to make it a new direct buffer.)
*/ */
public static boolean isBufferCopyNeededForWrite(ByteBuf byteBuf) { public static boolean isBufferCopyNeededForWrite(ByteBuf byteBuf) {
return !(byteBuf.hasMemoryAddress() || byteBuf.isDirect() && byteBuf.nioBufferCount() <= IOV_MAX); return !byteBuf.hasMemoryAddress() || !byteBuf.isDirect() || byteBuf.nioBufferCount() > IOV_MAX;
} }
} }