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:
parent
7922757575
commit
047da11086
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user