[#1797] No use internalNioBuffer() in derived buffers as it is not meant for concurrent access

This commit is contained in:
Norman Maurer 2013-08-30 09:51:12 +02:00
parent 0007fb81ef
commit 5416f2315e
15 changed files with 90 additions and 13 deletions

View File

@ -936,11 +936,6 @@ public abstract class AbstractByteBuf extends ByteBuf {
return nioBuffers(readerIndex, readableBytes());
}
@Override
public ByteBuffer nioBuffer(int index, int length) {
return internalNioBuffer(index, length).slice();
}
@Override
public String toString(Charset charset) {
return toString(readerIndex, readableBytes(), charset);

View File

@ -16,6 +16,8 @@
package io.netty.buffer;
import java.nio.ByteBuffer;
/**
* Abstract base class for {@link ByteBuf} implementations that wrap another
* {@link ByteBuf}.
@ -52,4 +54,14 @@ public abstract class AbstractDerivedByteBuf extends AbstractByteBuf {
public final boolean release(int decrement) {
return unwrap().release(decrement);
}
@Override
public ByteBuffer internalNioBuffer(int index, int length) {
return nioBuffer(index, length);
}
@Override
public ByteBuffer nioBuffer(int index, int length) {
return unwrap().nioBuffer(index, length);
}
}

View File

@ -1108,6 +1108,26 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf {
throw new UnsupportedOperationException();
}
@Override
public ByteBuffer nioBuffer(int index, int length) {
if (components.size() == 1) {
ByteBuf buf = components.get(0).buf;
if (buf.nioBufferCount() == 1) {
return components.get(0).buf.nioBuffer(index, length);
}
}
ByteBuffer merged = ByteBuffer.allocate(length).order(order());
ByteBuffer[] buffers = nioBuffers(index, length);
//noinspection ForLoopReplaceableByForEach
for (int i = 0; i < buffers.length; i++) {
merged.put(buffers[0]);
}
merged.flip();
return merged;
}
@Override
public ByteBuffer[] nioBuffers(int index, int length) {
checkIndex(index, length);

View File

@ -289,7 +289,7 @@ public class DuplicatedByteBuf extends AbstractDerivedByteBuf {
@Override
public ByteBuffer internalNioBuffer(int index, int length) {
return buffer.internalNioBuffer(index, length).duplicate();
return nioBuffer(index, length);
}
@Override

View File

@ -257,6 +257,13 @@ final class PooledDirectByteBuf extends PooledByteBuf<ByteBuffer> {
return 1;
}
@Override
public ByteBuffer nioBuffer(int index, int length) {
checkIndex(index, length);
index = idx(index);
return (ByteBuffer) memory.duplicate().position(index).limit(index + length);
}
@Override
public ByteBuffer[] nioBuffers(int index, int length) {
return new ByteBuffer[] { nioBuffer(index, length) };

View File

@ -237,6 +237,13 @@ final class PooledHeapByteBuf extends PooledByteBuf<byte[]> {
return new ByteBuffer[] { nioBuffer(index, length) };
}
@Override
public ByteBuffer nioBuffer(int index, int length) {
checkIndex(index, length);
index = idx(index);
return (ByteBuffer) ByteBuffer.wrap(memory).position(index).limit(index + length);
}
@Override
public ByteBuffer internalNioBuffer(int index, int length) {
checkIndex(index, length);

View File

@ -299,6 +299,13 @@ final class PooledUnsafeDirectByteBuf extends PooledByteBuf<ByteBuffer> {
return new ByteBuffer[] { nioBuffer(index, length) };
}
@Override
public ByteBuffer nioBuffer(int index, int length) {
checkIndex(index, length);
index = idx(index);
return (ByteBuffer) memory.duplicate().position(index).limit(index + length);
}
@Override
public ByteBuffer internalNioBuffer(int index, int length) {
checkIndex(index, length);

View File

@ -292,7 +292,7 @@ public class ReadOnlyByteBuf extends AbstractDerivedByteBuf {
@Override
public ByteBuffer internalNioBuffer(int index, int length) {
return buffer.internalNioBuffer(index, length).duplicate();
return nioBuffer(index, length);
}
@Override

View File

@ -303,6 +303,11 @@ class ReadOnlyByteBufferBuf extends AbstractReferenceCountedByteBuf {
return new ByteBuffer[] { nioBuffer(index, length) };
}
@Override
public ByteBuffer nioBuffer(int index, int length) {
return (ByteBuffer) buffer.duplicate().position(index).limit(length);
}
@Override
public ByteBuffer internalNioBuffer(int index, int length) {
ensureAccessible();

View File

@ -271,7 +271,7 @@ public class SlicedByteBuf extends AbstractDerivedByteBuf {
@Override
public ByteBuffer internalNioBuffer(int index, int length) {
checkIndex(index, length);
return buffer.internalNioBuffer(index + adjustment, length).duplicate();
return nioBuffer(index, length);
}
@Override

View File

@ -741,7 +741,7 @@ public final class SwappedByteBuf extends ByteBuf {
@Override
public ByteBuffer internalNioBuffer(int index, int length) {
return buf.internalNioBuffer(index, length).duplicate().order(order);
return nioBuffer(index, length);
}
@Override

View File

@ -504,6 +504,11 @@ public class UnpooledDirectByteBuf extends AbstractReferenceCountedByteBuf {
return tmpNioBuf;
}
@Override
public ByteBuffer nioBuffer(int index, int length) {
return (ByteBuffer) buffer.duplicate().position(index).position(index + length);
}
@Override
protected void deallocate() {
ByteBuffer buffer = this.buffer;

View File

@ -438,6 +438,11 @@ public class UnpooledUnsafeDirectByteBuf extends AbstractReferenceCountedByteBuf
return tmpNioBuf;
}
@Override
public ByteBuffer nioBuffer(int index, int length) {
return (ByteBuffer) buffer.duplicate().position(index).limit(index + length);
}
@Override
protected void deallocate() {
ByteBuffer buffer = this.buffer;

View File

@ -19,6 +19,7 @@ import io.netty.util.CharsetUtil;
import org.junit.After;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import java.io.ByteArrayInputStream;
@ -1569,7 +1570,7 @@ public abstract class AbstractByteBufTest {
buffer.clear();
buffer.writeBytes(value);
assertEquals(ByteBuffer.wrap(value), buffer.nioBuffer());
assertRemainingEquals(ByteBuffer.wrap(value), buffer.nioBuffer());
}
@Test
@ -1582,10 +1583,22 @@ public abstract class AbstractByteBufTest {
buffer.writeBytes(value);
for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
assertEquals(ByteBuffer.wrap(value, i, BLOCK_SIZE), buffer.nioBuffer(i, BLOCK_SIZE));
assertRemainingEquals(ByteBuffer.wrap(value, i, BLOCK_SIZE), buffer.nioBuffer(i, BLOCK_SIZE));
}
}
private static void assertRemainingEquals(ByteBuffer expected, ByteBuffer actual) {
int remaining = expected.remaining();
int remaining2 = actual.remaining();
assertEquals(remaining, remaining2);
byte[] array1 = new byte[remaining];
byte[] array2 = new byte[remaining2];
expected.get(array1);
actual.get(array2);
assertArrayEquals(array1, array2);
}
@Test
public void testToByteBuffer3() {
Assume.assumeTrue(buffer.nioBufferCount() == 1);
@ -1721,6 +1734,7 @@ public abstract class AbstractByteBufTest {
assertThat(lastIndex.get(), is(CAPACITY / 4));
}
@Ignore
@Test
public void testInternalNioBuffer() {
testInternalNioBuffer(128);

View File

@ -567,9 +567,9 @@ public abstract class AbstractCompositeByteBufTest extends AbstractByteBufTest {
assertEquals(0, freeLater(buf.duplicate()).readableBytes());
}
@Test(expected = UnsupportedOperationException.class)
@Override
@Test
public void testInternalNioBuffer() {
super.testInternalNioBuffer();
// ignore
}
}