Implement reference counting
- Related: #1029 - Replace Freeable with ReferenceCounted - Add AbstractReferenceCounted - Add AbstractReferenceCountedByteBuf - Add AbstractDerivedByteBuf - Add EmptyByteBuf
This commit is contained in:
parent
8f895a7e9a
commit
b9996908b1
@ -182,7 +182,7 @@ public abstract class AbstractByteBuf implements ByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf discardReadBytes() {
|
public ByteBuf discardReadBytes() {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
if (readerIndex == 0) {
|
if (readerIndex == 0) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -201,7 +201,7 @@ public abstract class AbstractByteBuf implements ByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf discardSomeReadBytes() {
|
public ByteBuf discardSomeReadBytes() {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
if (readerIndex == 0) {
|
if (readerIndex == 0) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -972,7 +972,7 @@ public abstract class AbstractByteBuf implements ByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
if (isFreed()) {
|
if (refCnt() == 0) {
|
||||||
return getClass().getSimpleName() + "(freed)";
|
return getClass().getSimpleName() + "(freed)";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -999,7 +999,7 @@ public abstract class AbstractByteBuf implements ByteBuf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected final void checkIndex(int index) {
|
protected final void checkIndex(int index) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
if (index < 0 || index >= capacity()) {
|
if (index < 0 || index >= capacity()) {
|
||||||
throw new IndexOutOfBoundsException(String.format(
|
throw new IndexOutOfBoundsException(String.format(
|
||||||
"index: %d (expected: range(0, %d))", index, capacity()));
|
"index: %d (expected: range(0, %d))", index, capacity()));
|
||||||
@ -1007,7 +1007,7 @@ public abstract class AbstractByteBuf implements ByteBuf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected final void checkIndex(int index, int fieldLength) {
|
protected final void checkIndex(int index, int fieldLength) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
if (fieldLength < 0) {
|
if (fieldLength < 0) {
|
||||||
throw new IllegalArgumentException("length: " + fieldLength + " (expected: >= 0)");
|
throw new IllegalArgumentException("length: " + fieldLength + " (expected: >= 0)");
|
||||||
}
|
}
|
||||||
@ -1023,7 +1023,7 @@ public abstract class AbstractByteBuf implements ByteBuf {
|
|||||||
* than the specified value.
|
* than the specified value.
|
||||||
*/
|
*/
|
||||||
protected final void checkReadableBytes(int minimumReadableBytes) {
|
protected final void checkReadableBytes(int minimumReadableBytes) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
if (readerIndex > writerIndex - minimumReadableBytes) {
|
if (readerIndex > writerIndex - minimumReadableBytes) {
|
||||||
throw new IndexOutOfBoundsException(String.format(
|
throw new IndexOutOfBoundsException(String.format(
|
||||||
"readerIndex(%d) + length(%d) exceeds writerIndex(%d): %s",
|
"readerIndex(%d) + length(%d) exceeds writerIndex(%d): %s",
|
||||||
@ -1031,8 +1031,8 @@ public abstract class AbstractByteBuf implements ByteBuf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final void checkUnfreed() {
|
protected final void ensureAccessible() {
|
||||||
if (isFreed()) {
|
if (refCnt() <= 0) {
|
||||||
throw new IllegalBufferAccessException();
|
throw new IllegalBufferAccessException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.netty.buffer;
|
||||||
|
|
||||||
|
public abstract class AbstractDerivedByteBuf extends AbstractByteBuf {
|
||||||
|
|
||||||
|
protected AbstractDerivedByteBuf(int maxCapacity) {
|
||||||
|
super(maxCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final int refCnt() {
|
||||||
|
return unwrap().refCnt();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void retain() { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void retain(int increment) { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean release() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean release(int decrement) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final ByteBuf suspendIntermediaryDeallocations() {
|
||||||
|
throw new UnsupportedOperationException("derived");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final ByteBuf resumeIntermediaryDeallocations() {
|
||||||
|
throw new UnsupportedOperationException("derived");
|
||||||
|
}
|
||||||
|
}
|
@ -22,7 +22,7 @@ import java.util.Collection;
|
|||||||
public abstract class AbstractMessageBuf<T> extends AbstractQueue<T> implements MessageBuf<T> {
|
public abstract class AbstractMessageBuf<T> extends AbstractQueue<T> implements MessageBuf<T> {
|
||||||
|
|
||||||
private final int maxCapacity;
|
private final int maxCapacity;
|
||||||
private boolean freed;
|
private int refCnt = 1;
|
||||||
|
|
||||||
protected AbstractMessageBuf(int maxCapacity) {
|
protected AbstractMessageBuf(int maxCapacity) {
|
||||||
if (maxCapacity < 0) {
|
if (maxCapacity < 0) {
|
||||||
@ -37,24 +37,79 @@ public abstract class AbstractMessageBuf<T> extends AbstractQueue<T> implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final boolean isFreed() {
|
public final int refCnt() {
|
||||||
return freed;
|
return refCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void free() {
|
public final void retain() {
|
||||||
if (freed) {
|
int refCnt = this.refCnt;
|
||||||
return;
|
if (refCnt <= 0) {
|
||||||
|
throw new IllegalBufferAccessException();
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
if (refCnt == Integer.MAX_VALUE) {
|
||||||
doFree();
|
throw new IllegalBufferAccessException("refCnt overflow");
|
||||||
} finally {
|
|
||||||
freed = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.refCnt = refCnt + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void doFree();
|
@Override
|
||||||
|
public final void retain(int increment) {
|
||||||
|
if (increment <= 0) {
|
||||||
|
throw new IllegalArgumentException("increment: " + increment + " (expected: > 0)");
|
||||||
|
}
|
||||||
|
|
||||||
|
int refCnt = this.refCnt;
|
||||||
|
if (refCnt <= 0) {
|
||||||
|
throw new IllegalBufferAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (refCnt > Integer.MAX_VALUE - increment) {
|
||||||
|
throw new IllegalBufferAccessException("refCnt overflow");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.refCnt = refCnt + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean release() {
|
||||||
|
int refCnt = this.refCnt;
|
||||||
|
if (refCnt <= 0) {
|
||||||
|
throw new IllegalBufferAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.refCnt = refCnt --;
|
||||||
|
if (refCnt == 0) {
|
||||||
|
deallocate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean release(int decrement) {
|
||||||
|
if (decrement <= 0) {
|
||||||
|
throw new IllegalArgumentException("decrement: " + decrement + " (expected: > 0)");
|
||||||
|
}
|
||||||
|
|
||||||
|
int refCnt = this.refCnt;
|
||||||
|
if (refCnt < decrement) {
|
||||||
|
throw new IllegalBufferAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.refCnt = refCnt -= decrement;
|
||||||
|
if (refCnt == 0) {
|
||||||
|
deallocate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void deallocate();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final int maxCapacity() {
|
public final int maxCapacity() {
|
||||||
@ -87,8 +142,8 @@ public abstract class AbstractMessageBuf<T> extends AbstractQueue<T> implements
|
|||||||
return size() <= maxCapacity - size;
|
return size() <= maxCapacity - size;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final void checkUnfreed() {
|
protected final void ensureAccessible() {
|
||||||
if (isFreed()) {
|
if (refCnt <= 0) {
|
||||||
throw new IllegalBufferAccessException();
|
throw new IllegalBufferAccessException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -133,7 +188,7 @@ public abstract class AbstractMessageBuf<T> extends AbstractQueue<T> implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int drainTo(Collection<? super T> c) {
|
public int drainTo(Collection<? super T> c) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
T o = poll();
|
T o = poll();
|
||||||
@ -148,7 +203,7 @@ public abstract class AbstractMessageBuf<T> extends AbstractQueue<T> implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int drainTo(Collection<? super T> c, int maxElements) {
|
public int drainTo(Collection<? super T> c, int maxElements) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
while (cnt < maxElements) {
|
while (cnt < maxElements) {
|
||||||
T o = poll();
|
T o = poll();
|
||||||
@ -163,7 +218,7 @@ public abstract class AbstractMessageBuf<T> extends AbstractQueue<T> implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
if (isFreed()) {
|
if (refCnt <= 0) {
|
||||||
return getClass().getSimpleName() + "(freed)";
|
return getClass().getSimpleName() + "(freed)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.buffer;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
|
||||||
|
|
||||||
|
public abstract class AbstractReferenceCounted implements ReferenceCounted {
|
||||||
|
|
||||||
|
private static final AtomicIntegerFieldUpdater<AbstractReferenceCounted> refCntUpdater =
|
||||||
|
AtomicIntegerFieldUpdater.newUpdater(AbstractReferenceCounted.class, "refCnt");
|
||||||
|
|
||||||
|
@SuppressWarnings("FieldMayBeFinal")
|
||||||
|
private volatile int refCnt = 1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int refCnt() {
|
||||||
|
return refCnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void retain() {
|
||||||
|
do {
|
||||||
|
int refCnt = this.refCnt;
|
||||||
|
if (refCnt <= 0) {
|
||||||
|
throw new IllegalBufferAccessException();
|
||||||
|
}
|
||||||
|
if (refCnt == Integer.MAX_VALUE) {
|
||||||
|
throw new IllegalBufferAccessException("refCnt overflow");
|
||||||
|
}
|
||||||
|
} while (!refCntUpdater.compareAndSet(this, refCnt, refCnt + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void retain(int increment) {
|
||||||
|
if (increment <= 0) {
|
||||||
|
throw new IllegalArgumentException("increment: " + increment + " (expected: > 0)");
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
int refCnt = this.refCnt;
|
||||||
|
if (refCnt <= 0) {
|
||||||
|
throw new IllegalBufferAccessException();
|
||||||
|
}
|
||||||
|
if (refCnt > Integer.MAX_VALUE - increment) {
|
||||||
|
throw new IllegalBufferAccessException("refCnt overflow");
|
||||||
|
}
|
||||||
|
} while (!refCntUpdater.compareAndSet(this, refCnt, refCnt + increment));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean release() {
|
||||||
|
for (;;) {
|
||||||
|
int refCnt = this.refCnt;
|
||||||
|
if (refCnt <= 0) {
|
||||||
|
throw new IllegalBufferAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (refCntUpdater.compareAndSet(this, refCnt, refCnt - 1)) {
|
||||||
|
if (refCnt == 1) {
|
||||||
|
deallocate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean release(int decrement) {
|
||||||
|
if (decrement <= 0) {
|
||||||
|
throw new IllegalArgumentException("decrement: " + decrement + " (expected: > 0)");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
int refCnt = this.refCnt;
|
||||||
|
if (refCnt < decrement) {
|
||||||
|
throw new IllegalBufferAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (refCntUpdater.compareAndSet(this, refCnt, refCnt - decrement)) {
|
||||||
|
if (refCnt == decrement) {
|
||||||
|
deallocate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void deallocate();
|
||||||
|
}
|
@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.netty.buffer;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
|
||||||
|
|
||||||
|
public abstract class AbstractReferenceCountedByteBuf extends AbstractByteBuf {
|
||||||
|
|
||||||
|
private static final AtomicIntegerFieldUpdater<AbstractReferenceCountedByteBuf> refCntUpdater =
|
||||||
|
AtomicIntegerFieldUpdater.newUpdater(AbstractReferenceCountedByteBuf.class, "refCnt");
|
||||||
|
|
||||||
|
@SuppressWarnings("FieldMayBeFinal")
|
||||||
|
private volatile int refCnt = 1;
|
||||||
|
|
||||||
|
protected AbstractReferenceCountedByteBuf(int maxCapacity) {
|
||||||
|
super(maxCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int refCnt() {
|
||||||
|
return refCnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void retain() {
|
||||||
|
do {
|
||||||
|
int refCnt = this.refCnt;
|
||||||
|
if (refCnt <= 0) {
|
||||||
|
throw new IllegalBufferAccessException();
|
||||||
|
}
|
||||||
|
if (refCnt == Integer.MAX_VALUE) {
|
||||||
|
throw new IllegalBufferAccessException("refCnt overflow");
|
||||||
|
}
|
||||||
|
} while (!refCntUpdater.compareAndSet(this, refCnt, refCnt + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void retain(int increment) {
|
||||||
|
if (increment <= 0) {
|
||||||
|
throw new IllegalArgumentException("increment: " + increment + " (expected: > 0)");
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
int refCnt = this.refCnt;
|
||||||
|
if (refCnt <= 0) {
|
||||||
|
throw new IllegalBufferAccessException();
|
||||||
|
}
|
||||||
|
if (refCnt > Integer.MAX_VALUE - increment) {
|
||||||
|
throw new IllegalBufferAccessException("refCnt overflow");
|
||||||
|
}
|
||||||
|
} while (!refCntUpdater.compareAndSet(this, refCnt, refCnt + increment));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean release() {
|
||||||
|
for (;;) {
|
||||||
|
int refCnt = this.refCnt;
|
||||||
|
if (refCnt <= 0) {
|
||||||
|
throw new IllegalBufferAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (refCntUpdater.compareAndSet(this, refCnt, refCnt - 1)) {
|
||||||
|
if (refCnt == 1) {
|
||||||
|
deallocate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean release(int decrement) {
|
||||||
|
if (decrement <= 0) {
|
||||||
|
throw new IllegalArgumentException("decrement: " + decrement + " (expected: > 0)");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
int refCnt = this.refCnt;
|
||||||
|
if (refCnt < decrement) {
|
||||||
|
throw new IllegalBufferAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (refCntUpdater.compareAndSet(this, refCnt, refCnt - decrement)) {
|
||||||
|
if (refCnt == decrement) {
|
||||||
|
deallocate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void deallocate();
|
||||||
|
}
|
@ -18,7 +18,7 @@ package io.netty.buffer;
|
|||||||
/**
|
/**
|
||||||
* A buffer to operate on
|
* A buffer to operate on
|
||||||
*/
|
*/
|
||||||
public interface Buf extends Freeable {
|
public interface Buf extends ReferenceCounted {
|
||||||
/**
|
/**
|
||||||
* The BufType which will be handled by the Buf implementation
|
* The BufType which will be handled by the Buf implementation
|
||||||
*/
|
*/
|
||||||
|
@ -43,20 +43,47 @@ public final class BufUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to call {@link Freeable#free()} if the specified message implements {@link Freeable}. If the specified
|
* Try to call {@link ReferenceCounted#retain()} if the specified message implements {@link ReferenceCounted}.
|
||||||
* message doesn't implement {@link Freeable}, this method does nothing.
|
* If the specified message doesn't implement {@link ReferenceCounted}, this method does nothing.
|
||||||
*/
|
*/
|
||||||
public static void free(Object msg) {
|
public static void retain(Object msg) {
|
||||||
if (msg instanceof Freeable) {
|
if (msg instanceof ReferenceCounted) {
|
||||||
try {
|
((ReferenceCounted) msg).retain();
|
||||||
((Freeable) msg).free();
|
|
||||||
} catch (UnsupportedOperationException e) {
|
|
||||||
// This can happen for derived buffers
|
|
||||||
// TODO: Think about this
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to call {@link ReferenceCounted#retain()} if the specified message implements {@link ReferenceCounted}.
|
||||||
|
* If the specified message doesn't implement {@link ReferenceCounted}, this method does nothing.
|
||||||
|
*/
|
||||||
|
public static void retain(Object msg, int increment) {
|
||||||
|
if (msg instanceof ReferenceCounted) {
|
||||||
|
((ReferenceCounted) msg).retain(increment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to call {@link ReferenceCounted#release()} if the specified message implements {@link ReferenceCounted}.
|
||||||
|
* If the specified message doesn't implement {@link ReferenceCounted}, this method does nothing.
|
||||||
|
*/
|
||||||
|
public static boolean release(Object msg) {
|
||||||
|
if (msg instanceof ReferenceCounted) {
|
||||||
|
return ((ReferenceCounted) msg).release();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to call {@link ReferenceCounted#release()} if the specified message implements {@link ReferenceCounted}.
|
||||||
|
* If the specified message doesn't implement {@link ReferenceCounted}, this method does nothing.
|
||||||
|
*/
|
||||||
|
public static boolean release(Object msg, int decrement) {
|
||||||
|
if (msg instanceof ReferenceCounted) {
|
||||||
|
return ((ReferenceCounted) msg).release(decrement);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a <a href="http://en.wikipedia.org/wiki/Hex_dump">hex dump</a>
|
* Returns a <a href="http://en.wikipedia.org/wiki/Hex_dump">hex dump</a>
|
||||||
* of the specified buffer's readable bytes.
|
* of the specified buffer's readable bytes.
|
||||||
|
@ -1914,19 +1914,4 @@ public interface ByteBuf extends Buf, Comparable<ByteBuf> {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
String toString();
|
String toString();
|
||||||
|
|
||||||
/**
|
|
||||||
* Deallocates the internal memory block of this buffer or returns it to the allocator or pool it came from.
|
|
||||||
* The result of accessing a released buffer is unspecified and can even cause JVM crash.
|
|
||||||
*
|
|
||||||
* @throws UnsupportedOperationException if this buffer is derived
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
void free();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns {@code true} if and only if this buffer has been deallocated by {@link #free()}.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
boolean isFreed();
|
|
||||||
}
|
}
|
||||||
|
@ -16,15 +16,9 @@
|
|||||||
package io.netty.buffer;
|
package io.netty.buffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A packet which is send or receive. The contract for a {@link ByteBufHolder} is the
|
* A packet which is send or receive.
|
||||||
* following:
|
|
||||||
*
|
|
||||||
* When send a {@link ByteBufHolder} the {@link ByteBufHolder} will be freed by calling {@link #free()}
|
|
||||||
* in the actual transport implementation. When receive a {@link ByteBufHolder} the {@link #free()}
|
|
||||||
* must be called once is is processed.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public interface ByteBufHolder extends Freeable {
|
public interface ByteBufHolder extends ReferenceCounted {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the data which is held by this {@link ByteBufHolder}.
|
* Return the data which is held by this {@link ByteBufHolder}.
|
||||||
@ -33,20 +27,7 @@ public interface ByteBufHolder extends Freeable {
|
|||||||
ByteBuf data();
|
ByteBuf data();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a copy of this {@link ByteBufHolder} which can be used even after {@link #free()}
|
* Create a deep copy of this {@link ByteBufHolder}.
|
||||||
* is called.
|
|
||||||
*/
|
*/
|
||||||
ByteBufHolder copy();
|
ByteBufHolder copy();
|
||||||
|
|
||||||
/**
|
|
||||||
* Free of the resources that are hold by this instance. This includes the {@link ByteBuf}.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
void free();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns {@code true} if and only if this instances was freed.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
boolean isFreed();
|
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,9 @@ package io.netty.buffer;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class DefaultByteBufHolder implements ByteBufHolder {
|
public class DefaultByteBufHolder implements ByteBufHolder {
|
||||||
|
|
||||||
private final ByteBuf data;
|
private final ByteBuf data;
|
||||||
|
|
||||||
public DefaultByteBufHolder(ByteBuf data) {
|
public DefaultByteBufHolder(ByteBuf data) {
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
throw new NullPointerException("data");
|
throw new NullPointerException("data");
|
||||||
@ -34,25 +36,40 @@ public class DefaultByteBufHolder implements ByteBufHolder {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf data() {
|
public ByteBuf data() {
|
||||||
if (data.isFreed()) {
|
if (data.refCnt() <= 0) {
|
||||||
throw new IllegalBufferAccessException();
|
throw new IllegalBufferAccessException();
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void free() {
|
|
||||||
data.free();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFreed() {
|
|
||||||
return data.isFreed();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBufHolder copy() {
|
public ByteBufHolder copy() {
|
||||||
return new DefaultByteBufHolder(data().copy());
|
return new DefaultByteBufHolder(data.copy());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int refCnt() {
|
||||||
|
return data.refCnt();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void retain() {
|
||||||
|
data.retain();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void retain(int increment) {
|
||||||
|
data.retain(increment);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean release() {
|
||||||
|
return data.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean release(int decrement) {
|
||||||
|
return data.release(decrement);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -40,7 +40,7 @@ import java.util.Queue;
|
|||||||
* is recommended to use {@link Unpooled#wrappedBuffer(ByteBuf...)}
|
* is recommended to use {@link Unpooled#wrappedBuffer(ByteBuf...)}
|
||||||
* instead of calling the constructor explicitly.
|
* instead of calling the constructor explicitly.
|
||||||
*/
|
*/
|
||||||
public class DefaultCompositeByteBuf extends AbstractByteBuf implements CompositeByteBuf {
|
public class DefaultCompositeByteBuf extends AbstractReferenceCountedByteBuf implements CompositeByteBuf {
|
||||||
|
|
||||||
private static final ByteBuffer[] EMPTY_NIOBUFFERS = new ByteBuffer[0];
|
private static final ByteBuffer[] EMPTY_NIOBUFFERS = new ByteBuffer[0];
|
||||||
|
|
||||||
@ -1293,7 +1293,7 @@ public class DefaultCompositeByteBuf extends AbstractByteBuf implements Composit
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (suspendedDeallocations == null) {
|
if (suspendedDeallocations == null) {
|
||||||
buf.free(); // We should not get a NPE here. If so, it must be a bug.
|
buf.release(); // We should not get a NPE here. If so, it must be a bug.
|
||||||
} else {
|
} else {
|
||||||
suspendedDeallocations.add(buf);
|
suspendedDeallocations.add(buf);
|
||||||
}
|
}
|
||||||
@ -1531,12 +1531,7 @@ public class DefaultCompositeByteBuf extends AbstractByteBuf implements Composit
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFreed() {
|
protected void deallocate() {
|
||||||
return freed;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void free() {
|
|
||||||
if (freed) {
|
if (freed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1552,6 +1547,7 @@ public class DefaultCompositeByteBuf extends AbstractByteBuf implements Composit
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompositeByteBuf suspendIntermediaryDeallocations() {
|
public CompositeByteBuf suspendIntermediaryDeallocations() {
|
||||||
|
ensureAccessible();
|
||||||
if (suspendedDeallocations == null) {
|
if (suspendedDeallocations == null) {
|
||||||
suspendedDeallocations = new ArrayDeque<ByteBuf>(2);
|
suspendedDeallocations = new ArrayDeque<ByteBuf>(2);
|
||||||
}
|
}
|
||||||
@ -1568,7 +1564,7 @@ public class DefaultCompositeByteBuf extends AbstractByteBuf implements Composit
|
|||||||
this.suspendedDeallocations = null;
|
this.suspendedDeallocations = null;
|
||||||
|
|
||||||
for (ByteBuf buf: suspendedDeallocations) {
|
for (ByteBuf buf: suspendedDeallocations) {
|
||||||
buf.free();
|
buf.release();
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ final class DefaultMessageBuf<T> extends AbstractMessageBuf<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doFree() {
|
protected void deallocate() {
|
||||||
elements = null;
|
elements = null;
|
||||||
head = 0;
|
head = 0;
|
||||||
tail = 0;
|
tail = 0;
|
||||||
|
@ -29,7 +29,7 @@ import java.nio.channels.ScatteringByteChannel;
|
|||||||
* parent. It is recommended to use {@link ByteBuf#duplicate()} instead
|
* parent. It is recommended to use {@link ByteBuf#duplicate()} instead
|
||||||
* of calling the constructor explicitly.
|
* of calling the constructor explicitly.
|
||||||
*/
|
*/
|
||||||
public class DuplicatedByteBuf extends AbstractByteBuf {
|
public class DuplicatedByteBuf extends AbstractDerivedByteBuf {
|
||||||
|
|
||||||
private final ByteBuf buffer;
|
private final ByteBuf buffer;
|
||||||
|
|
||||||
@ -231,25 +231,5 @@ public class DuplicatedByteBuf extends AbstractByteBuf {
|
|||||||
public ByteBuffer[] nioBuffers(int index, int length) {
|
public ByteBuffer[] nioBuffers(int index, int length) {
|
||||||
return buffer.nioBuffers(index, length);
|
return buffer.nioBuffers(index, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFreed() {
|
|
||||||
return buffer.isFreed();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void free() {
|
|
||||||
throw new UnsupportedOperationException("derived");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf suspendIntermediaryDeallocations() {
|
|
||||||
throw new UnsupportedOperationException("derived");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf resumeIntermediaryDeallocations() {
|
|
||||||
throw new UnsupportedOperationException("derived");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
850
buffer/src/main/java/io/netty/buffer/EmptyByteBuf.java
Normal file
850
buffer/src/main/java/io/netty/buffer/EmptyByteBuf.java
Normal file
@ -0,0 +1,850 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.netty.buffer;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.nio.ReadOnlyBufferException;
|
||||||
|
import java.nio.channels.GatheringByteChannel;
|
||||||
|
import java.nio.channels.ScatteringByteChannel;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
public final class EmptyByteBuf implements ByteBuf {
|
||||||
|
|
||||||
|
private static final byte[] EMPTY_ARRAY = new byte[0];
|
||||||
|
|
||||||
|
public static final EmptyByteBuf INSTANCE_BE = new EmptyByteBuf(ByteOrder.BIG_ENDIAN);
|
||||||
|
public static final EmptyByteBuf INSTANCE_LE = new EmptyByteBuf(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
|
||||||
|
private final ByteOrder order;
|
||||||
|
private final ByteBuffer nioBuf = ByteBuffer.allocateDirect(0);
|
||||||
|
private final byte[] array = EMPTY_ARRAY;
|
||||||
|
private final String str;
|
||||||
|
|
||||||
|
private EmptyByteBuf(ByteOrder order) {
|
||||||
|
this.order = order;
|
||||||
|
nioBuf.order(order);
|
||||||
|
str = getClass().getSimpleName() + (order == ByteOrder.BIG_ENDIAN? "BE" : "LE");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int capacity() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf capacity(int newCapacity) {
|
||||||
|
throw new ReadOnlyBufferException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBufAllocator alloc() {
|
||||||
|
return UnpooledByteBufAllocator.HEAP_BY_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteOrder order() {
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf unwrap() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDirect() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int maxCapacity() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf order(ByteOrder endianness) {
|
||||||
|
if (endianness == null) {
|
||||||
|
throw new NullPointerException("endianness");
|
||||||
|
}
|
||||||
|
if (endianness == ByteOrder.BIG_ENDIAN) {
|
||||||
|
return INSTANCE_BE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return INSTANCE_LE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int readerIndex() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf readerIndex(int readerIndex) {
|
||||||
|
return checkIndex(readerIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int writerIndex() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf writerIndex(int writerIndex) {
|
||||||
|
return checkIndex(writerIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setIndex(int readerIndex, int writerIndex) {
|
||||||
|
checkIndex(readerIndex);
|
||||||
|
checkIndex(writerIndex);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int readableBytes() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int writableBytes() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int maxWritableBytes() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isReadable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean readable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWritable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean writable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf clear() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf markReaderIndex() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf resetReaderIndex() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf markWriterIndex() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf resetWriterIndex() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf discardReadBytes() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf discardSomeReadBytes() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf ensureWritable(int minWritableBytes) {
|
||||||
|
if (minWritableBytes < 0) {
|
||||||
|
throw new IllegalArgumentException("minWritableBytes: " + minWritableBytes + " (expected: >= 0)");
|
||||||
|
}
|
||||||
|
if (minWritableBytes != 0) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf ensureWritableBytes(int minWritableBytes) {
|
||||||
|
return ensureWritable(minWritableBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int ensureWritable(int minWritableBytes, boolean force) {
|
||||||
|
if (minWritableBytes < 0) {
|
||||||
|
throw new IllegalArgumentException("minWritableBytes: " + minWritableBytes + " (expected: >= 0)");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minWritableBytes == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getBoolean(int index) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte getByte(int index) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public short getUnsignedByte(int index) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public short getShort(int index) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getUnsignedShort(int index) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMedium(int index) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getUnsignedMedium(int index) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getInt(int index) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getUnsignedInt(int index) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getLong(int index) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char getChar(int index) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getFloat(int index) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getDouble(int index) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf getBytes(int index, ByteBuf dst) {
|
||||||
|
return checkIndex(index, dst.writableBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf getBytes(int index, ByteBuf dst, int length) {
|
||||||
|
return checkIndex(index, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
|
||||||
|
return checkIndex(index, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf getBytes(int index, byte[] dst) {
|
||||||
|
return checkIndex(index, dst.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) {
|
||||||
|
return checkIndex(index, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf getBytes(int index, ByteBuffer dst) {
|
||||||
|
return checkIndex(index, dst.remaining());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf getBytes(int index, OutputStream out, int length) {
|
||||||
|
return checkIndex(index, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBytes(int index, GatheringByteChannel out, int length) {
|
||||||
|
checkIndex(index, length);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setBoolean(int index, boolean value) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setByte(int index, int value) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setShort(int index, int value) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setMedium(int index, int value) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setInt(int index, int value) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setLong(int index, long value) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setChar(int index, int value) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setFloat(int index, float value) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setDouble(int index, double value) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setBytes(int index, ByteBuf src) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setBytes(int index, ByteBuf src, int length) {
|
||||||
|
return checkIndex(index, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
|
||||||
|
return checkIndex(index, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setBytes(int index, byte[] src) {
|
||||||
|
return checkIndex(index, src.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) {
|
||||||
|
return checkIndex(index, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setBytes(int index, ByteBuffer src) {
|
||||||
|
return checkIndex(index, src.remaining());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int setBytes(int index, InputStream in, int length) {
|
||||||
|
checkIndex(index, length);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int setBytes(int index, ScatteringByteChannel in, int length) {
|
||||||
|
checkIndex(index, length);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setZero(int index, int length) {
|
||||||
|
return checkIndex(index, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean readBoolean() {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte readByte() {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public short readUnsignedByte() {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public short readShort() {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int readUnsignedShort() {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int readMedium() {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int readUnsignedMedium() {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int readInt() {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long readUnsignedInt() {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long readLong() {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char readChar() {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float readFloat() {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double readDouble() {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf readBytes(int length) {
|
||||||
|
return checkLength(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf readSlice(int length) {
|
||||||
|
return checkLength(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf readBytes(ByteBuf dst) {
|
||||||
|
return checkLength(dst.writableBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf readBytes(ByteBuf dst, int length) {
|
||||||
|
return checkLength(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf readBytes(ByteBuf dst, int dstIndex, int length) {
|
||||||
|
return checkLength(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf readBytes(byte[] dst) {
|
||||||
|
return checkLength(dst.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf readBytes(byte[] dst, int dstIndex, int length) {
|
||||||
|
return checkLength(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf readBytes(ByteBuffer dst) {
|
||||||
|
return checkLength(dst.remaining());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf readBytes(OutputStream out, int length) {
|
||||||
|
return checkLength(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int readBytes(GatheringByteChannel out, int length) {
|
||||||
|
checkLength(length);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf skipBytes(int length) {
|
||||||
|
return checkLength(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf writeBoolean(boolean value) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf writeByte(int value) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf writeShort(int value) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf writeMedium(int value) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf writeInt(int value) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf writeLong(long value) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf writeChar(int value) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf writeFloat(float value) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf writeDouble(double value) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf writeBytes(ByteBuf src) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf writeBytes(ByteBuf src, int length) {
|
||||||
|
return checkLength(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf writeBytes(ByteBuf src, int srcIndex, int length) {
|
||||||
|
return checkLength(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf writeBytes(byte[] src) {
|
||||||
|
return checkLength(src.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf writeBytes(byte[] src, int srcIndex, int length) {
|
||||||
|
return checkLength(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf writeBytes(ByteBuffer src) {
|
||||||
|
return checkLength(src.remaining());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int writeBytes(InputStream in, int length) {
|
||||||
|
checkLength(length);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int writeBytes(ScatteringByteChannel in, int length) {
|
||||||
|
checkLength(length);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf writeZero(int length) {
|
||||||
|
return checkLength(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int indexOf(int fromIndex, int toIndex, byte value) {
|
||||||
|
checkIndex(fromIndex);
|
||||||
|
checkIndex(toIndex);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int indexOf(int fromIndex, int toIndex, ByteBufIndexFinder indexFinder) {
|
||||||
|
checkIndex(fromIndex);
|
||||||
|
checkIndex(toIndex);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int bytesBefore(byte value) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int bytesBefore(ByteBufIndexFinder indexFinder) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int bytesBefore(int length, byte value) {
|
||||||
|
checkLength(length);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int bytesBefore(int length, ByteBufIndexFinder indexFinder) {
|
||||||
|
checkLength(length);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int bytesBefore(int index, int length, byte value) {
|
||||||
|
checkIndex(index, length);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int bytesBefore(int index, int length, ByteBufIndexFinder indexFinder) {
|
||||||
|
checkIndex(index, length);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf copy() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf copy(int index, int length) {
|
||||||
|
return checkIndex(index, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf slice() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf slice(int index, int length) {
|
||||||
|
return checkIndex(index, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf duplicate() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int nioBufferCount() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuffer nioBuffer() {
|
||||||
|
return nioBuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuffer nioBuffer(int index, int length) {
|
||||||
|
checkIndex(index, length);
|
||||||
|
return nioBuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuffer[] nioBuffers() {
|
||||||
|
return new ByteBuffer[] { nioBuf };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuffer[] nioBuffers(int index, int length) {
|
||||||
|
checkIndex(index, length);
|
||||||
|
return new ByteBuffer[] { nioBuf };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasArray() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] array() {
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int arrayOffset() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString(Charset charset) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString(int index, int length, Charset charset) {
|
||||||
|
checkIndex(index, length);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf suspendIntermediaryDeallocations() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf resumeIntermediaryDeallocations() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return obj instanceof ByteBuf && !((ByteBuf) obj).isReadable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(ByteBuf buffer) {
|
||||||
|
return buffer.isReadable()? -1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BufType type() {
|
||||||
|
return BufType.BYTE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isReadable(int size) {
|
||||||
|
checkLength(size);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWritable(int size) {
|
||||||
|
checkLength(size);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int refCnt() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void retain() { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void retain(int increment) { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean release() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean release(int decrement) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ByteBuf checkIndex(int index) {
|
||||||
|
if (index != 0) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ByteBuf checkIndex(int index, int length) {
|
||||||
|
if (length < 0) {
|
||||||
|
throw new IllegalArgumentException("length: " + length);
|
||||||
|
}
|
||||||
|
if (index != 0 || length != 0) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ByteBuf checkLength(int length) {
|
||||||
|
if (length < 0) {
|
||||||
|
throw new IllegalArgumentException("length: " + length + " (expected: >= 0)");
|
||||||
|
}
|
||||||
|
if (length != 0) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
@ -195,13 +195,33 @@ public abstract class FilteredMessageBuf implements MessageBuf<Object> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFreed() {
|
public boolean unfoldAndAdd(Object o) {
|
||||||
return buf.isFreed();
|
return buf.unfoldAndAdd(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void free() {
|
public int refCnt() {
|
||||||
buf.free();
|
return buf.refCnt();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void retain() {
|
||||||
|
buf.retain();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void retain(int increment) {
|
||||||
|
buf.retain(increment);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean release() {
|
||||||
|
return buf.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean release(int decrement) {
|
||||||
|
return buf.release(decrement);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2013 The Netty Project
|
|
||||||
*
|
|
||||||
* The Netty Project licenses this file to you under the Apache License,
|
|
||||||
* version 2.0 (the "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at:
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
package io.netty.buffer;
|
|
||||||
|
|
||||||
public interface Freeable {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns {@code true} if and only if this resource has been deallocated by {@link #free()}.
|
|
||||||
*/
|
|
||||||
boolean isFreed();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deallocates the resources.
|
|
||||||
*
|
|
||||||
* The result of accessing a freed resource is unspecified and can even cause JVM crash.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void free();
|
|
||||||
}
|
|
@ -23,7 +23,7 @@ import java.nio.ByteOrder;
|
|||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
|
|
||||||
abstract class PooledByteBuf<T> extends AbstractByteBuf {
|
abstract class PooledByteBuf<T> extends AbstractReferenceCountedByteBuf {
|
||||||
|
|
||||||
private final ResourceLeak leak = leakDetector.open(this);
|
private final ResourceLeak leak = leakDetector.open(this);
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ abstract class PooledByteBuf<T> extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final ByteBuf capacity(int newCapacity) {
|
public final ByteBuf capacity(int newCapacity) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
|
|
||||||
// If the request capacity does not require reallocation, just update the length of the memory.
|
// If the request capacity does not require reallocation, just update the length of the memory.
|
||||||
if (chunk.unpooled) {
|
if (chunk.unpooled) {
|
||||||
@ -144,7 +144,7 @@ abstract class PooledByteBuf<T> extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final ByteBuf suspendIntermediaryDeallocations() {
|
public final ByteBuf suspendIntermediaryDeallocations() {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
if (suspendedDeallocations == null) {
|
if (suspendedDeallocations == null) {
|
||||||
suspendedDeallocations = new ArrayDeque<Allocation<T>>(2);
|
suspendedDeallocations = new ArrayDeque<Allocation<T>>(2);
|
||||||
}
|
}
|
||||||
@ -153,7 +153,6 @@ abstract class PooledByteBuf<T> extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final ByteBuf resumeIntermediaryDeallocations() {
|
public final ByteBuf resumeIntermediaryDeallocations() {
|
||||||
checkUnfreed();
|
|
||||||
if (suspendedDeallocations == null) {
|
if (suspendedDeallocations == null) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -172,12 +171,7 @@ abstract class PooledByteBuf<T> extends AbstractByteBuf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final boolean isFreed() {
|
protected final void deallocate() {
|
||||||
return memory == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final void free() {
|
|
||||||
if (handle >= 0) {
|
if (handle >= 0) {
|
||||||
resumeIntermediaryDeallocations();
|
resumeIntermediaryDeallocations();
|
||||||
final long handle = this.handle;
|
final long handle = this.handle;
|
||||||
|
@ -21,7 +21,7 @@ import java.util.Queue;
|
|||||||
|
|
||||||
final class QueueBackedMessageBuf<T> extends AbstractMessageBuf<T> {
|
final class QueueBackedMessageBuf<T> extends AbstractMessageBuf<T> {
|
||||||
|
|
||||||
private final Queue<T> queue;
|
private Queue<T> queue;
|
||||||
|
|
||||||
QueueBackedMessageBuf(Queue<T> queue) {
|
QueueBackedMessageBuf(Queue<T> queue) {
|
||||||
super(Integer.MAX_VALUE);
|
super(Integer.MAX_VALUE);
|
||||||
@ -36,19 +36,19 @@ final class QueueBackedMessageBuf<T> extends AbstractMessageBuf<T> {
|
|||||||
if (e == null) {
|
if (e == null) {
|
||||||
throw new NullPointerException("e");
|
throw new NullPointerException("e");
|
||||||
}
|
}
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
return isWritable() && queue.offer(e);
|
return isWritable() && queue.offer(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T poll() {
|
public T poll() {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
return queue.poll();
|
return queue.poll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T peek() {
|
public T peek() {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
return queue.peek();
|
return queue.peek();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,66 +64,66 @@ final class QueueBackedMessageBuf<T> extends AbstractMessageBuf<T> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean contains(Object o) {
|
public boolean contains(Object o) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
return queue.contains(o);
|
return queue.contains(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<T> iterator() {
|
public Iterator<T> iterator() {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
return queue.iterator();
|
return queue.iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object[] toArray() {
|
public Object[] toArray() {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
return queue.toArray();
|
return queue.toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <E> E[] toArray(E[] a) {
|
public <E> E[] toArray(E[] a) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
return queue.toArray(a);
|
return queue.toArray(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean remove(Object o) {
|
public boolean remove(Object o) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
return queue.remove(o);
|
return queue.remove(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean containsAll(Collection<?> c) {
|
public boolean containsAll(Collection<?> c) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
return queue.containsAll(c);
|
return queue.containsAll(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean addAll(Collection<? extends T> c) {
|
public boolean addAll(Collection<? extends T> c) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
return isWritable(c.size()) && queue.addAll(c);
|
return isWritable(c.size()) && queue.addAll(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean removeAll(Collection<?> c) {
|
public boolean removeAll(Collection<?> c) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
return queue.removeAll(c);
|
return queue.removeAll(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean retainAll(Collection<?> c) {
|
public boolean retainAll(Collection<?> c) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
return queue.retainAll(c);
|
return queue.retainAll(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clear() {
|
public void clear() {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
queue.clear();
|
queue.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doFree() {
|
protected void deallocate() {
|
||||||
clear();
|
queue = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ import java.nio.channels.ScatteringByteChannel;
|
|||||||
* recommended to use {@link Unpooled#unmodifiableBuffer(ByteBuf)}
|
* recommended to use {@link Unpooled#unmodifiableBuffer(ByteBuf)}
|
||||||
* instead of calling the constructor explicitly.
|
* instead of calling the constructor explicitly.
|
||||||
*/
|
*/
|
||||||
public class ReadOnlyByteBuf extends AbstractByteBuf {
|
public class ReadOnlyByteBuf extends AbstractDerivedByteBuf {
|
||||||
|
|
||||||
private final ByteBuf buffer;
|
private final ByteBuf buffer;
|
||||||
|
|
||||||
@ -229,24 +229,4 @@ public class ReadOnlyByteBuf extends AbstractByteBuf {
|
|||||||
public ByteBuf capacity(int newCapacity) {
|
public ByteBuf capacity(int newCapacity) {
|
||||||
throw new ReadOnlyBufferException();
|
throw new ReadOnlyBufferException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFreed() {
|
|
||||||
return buffer.isFreed();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void free() {
|
|
||||||
throw new UnsupportedOperationException("derived");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf suspendIntermediaryDeallocations() {
|
|
||||||
throw new UnsupportedOperationException("derived");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf resumeIntermediaryDeallocations() {
|
|
||||||
throw new UnsupportedOperationException("derived");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
55
buffer/src/main/java/io/netty/buffer/ReferenceCounted.java
Normal file
55
buffer/src/main/java/io/netty/buffer/ReferenceCounted.java
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A reference-counted object that requires explicit deallocation.
|
||||||
|
* <p>
|
||||||
|
* When a new {@link ReferenceCounted} is instantiated, it starts with the reference count of {@code 1}.
|
||||||
|
* {@link #retain()} increases the reference count, and {@link #release()} decreases the reference count.
|
||||||
|
* If the reference count is decreased to {@code 0}, the object will be deallocated explicitly, and accessing
|
||||||
|
* the deallocated object will usually result in an access violation.
|
||||||
|
*/
|
||||||
|
public interface ReferenceCounted {
|
||||||
|
/**
|
||||||
|
* Returns the reference count of this object. If {@code 0}, it means this object has been deallocated.
|
||||||
|
*/
|
||||||
|
int refCnt();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increases the reference count by {@code 1}.
|
||||||
|
*/
|
||||||
|
void retain();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increases the reference count by the specified {@code increment}.
|
||||||
|
*/
|
||||||
|
void retain(int increment);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decreases the reference count by {@code 1}.
|
||||||
|
*
|
||||||
|
* @return {@code true} if and only if the reference count became {@code 0} and this object has been deallocated
|
||||||
|
*/
|
||||||
|
boolean release();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decreases the reference count by the specified {@code decrement}.
|
||||||
|
*
|
||||||
|
* @return {@code true} if and only if the reference count became {@code 0} and this object has been deallocated
|
||||||
|
*/
|
||||||
|
boolean release(int decrement);
|
||||||
|
}
|
@ -30,7 +30,7 @@ import java.nio.channels.ScatteringByteChannel;
|
|||||||
* {@link ByteBuf#slice(int, int)} instead of calling the constructor
|
* {@link ByteBuf#slice(int, int)} instead of calling the constructor
|
||||||
* explicitly.
|
* explicitly.
|
||||||
*/
|
*/
|
||||||
public class SlicedByteBuf extends AbstractByteBuf {
|
public class SlicedByteBuf extends AbstractDerivedByteBuf {
|
||||||
|
|
||||||
private final ByteBuf buffer;
|
private final ByteBuf buffer;
|
||||||
private final int adjustment;
|
private final int adjustment;
|
||||||
@ -282,24 +282,4 @@ public class SlicedByteBuf extends AbstractByteBuf {
|
|||||||
checkIndex(index, length);
|
checkIndex(index, length);
|
||||||
return buffer.nioBuffers(index, length);
|
return buffer.nioBuffers(index, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFreed() {
|
|
||||||
return buffer.isFreed();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void free() {
|
|
||||||
throw new UnsupportedOperationException("derived");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf suspendIntermediaryDeallocations() {
|
|
||||||
throw new UnsupportedOperationException("derived");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf resumeIntermediaryDeallocations() {
|
|
||||||
throw new UnsupportedOperationException("derived");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -816,13 +816,28 @@ public final class SwappedByteBuf implements ByteBuf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFreed() {
|
public int refCnt() {
|
||||||
return buf.isFreed();
|
return buf.refCnt();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void free() {
|
public void retain() {
|
||||||
buf.free();
|
buf.retain();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void retain(int increment) {
|
||||||
|
buf.retain(increment);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean release() {
|
||||||
|
return buf.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean release(int decrement) {
|
||||||
|
return buf.release(decrement);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -15,14 +15,9 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.buffer;
|
package io.netty.buffer;
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
import java.nio.CharBuffer;
|
import java.nio.CharBuffer;
|
||||||
import java.nio.ReadOnlyBufferException;
|
|
||||||
import java.nio.channels.GatheringByteChannel;
|
|
||||||
import java.nio.channels.ScatteringByteChannel;
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -97,192 +92,7 @@ public final class Unpooled {
|
|||||||
/**
|
/**
|
||||||
* A buffer whose capacity is {@code 0}.
|
* A buffer whose capacity is {@code 0}.
|
||||||
*/
|
*/
|
||||||
public static final ByteBuf EMPTY_BUFFER = new AbstractByteBuf(0) {
|
public static final ByteBuf EMPTY_BUFFER = EmptyByteBuf.INSTANCE_BE;
|
||||||
@Override
|
|
||||||
public int capacity() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf capacity(int newCapacity) {
|
|
||||||
throw new ReadOnlyBufferException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBufAllocator alloc() {
|
|
||||||
return ALLOC;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteOrder order() {
|
|
||||||
return BIG_ENDIAN;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf unwrap() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDirect() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte getByte(int index) {
|
|
||||||
throw new IndexOutOfBoundsException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public short getShort(int index) {
|
|
||||||
throw new IndexOutOfBoundsException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getUnsignedMedium(int index) {
|
|
||||||
throw new IndexOutOfBoundsException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getInt(int index) {
|
|
||||||
throw new IndexOutOfBoundsException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getLong(int index) {
|
|
||||||
throw new IndexOutOfBoundsException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
|
|
||||||
throw new IndexOutOfBoundsException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) {
|
|
||||||
throw new IndexOutOfBoundsException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf getBytes(int index, ByteBuffer dst) {
|
|
||||||
throw new IndexOutOfBoundsException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf getBytes(int index, OutputStream out, int length) {
|
|
||||||
throw new IndexOutOfBoundsException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getBytes(int index, GatheringByteChannel out, int length) {
|
|
||||||
throw new IndexOutOfBoundsException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf setByte(int index, int value) {
|
|
||||||
throw new ReadOnlyBufferException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf setShort(int index, int value) {
|
|
||||||
throw new ReadOnlyBufferException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf setMedium(int index, int value) {
|
|
||||||
throw new ReadOnlyBufferException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf setInt(int index, int value) {
|
|
||||||
throw new ReadOnlyBufferException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf setLong(int index, long value) {
|
|
||||||
throw new ReadOnlyBufferException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
|
|
||||||
throw new ReadOnlyBufferException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) {
|
|
||||||
throw new ReadOnlyBufferException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf setBytes(int index, ByteBuffer src) {
|
|
||||||
throw new ReadOnlyBufferException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int setBytes(int index, InputStream in, int length) {
|
|
||||||
throw new ReadOnlyBufferException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int setBytes(int index, ScatteringByteChannel in, int length) {
|
|
||||||
throw new ReadOnlyBufferException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf copy(int index, int length) {
|
|
||||||
throw new IndexOutOfBoundsException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int nioBufferCount() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuffer nioBuffer(int index, int length) {
|
|
||||||
return ByteBuffer.allocate(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuffer[] nioBuffers(int index, int length) {
|
|
||||||
return new ByteBuffer[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasArray() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] array() {
|
|
||||||
return new byte[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int arrayOffset() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf suspendIntermediaryDeallocations() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf resumeIntermediaryDeallocations() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void free() {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFreed() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public static <T> MessageBuf<T> messageBuffer() {
|
public static <T> MessageBuf<T> messageBuffer() {
|
||||||
return new DefaultMessageBuf<T>();
|
return new DefaultMessageBuf<T>();
|
||||||
|
@ -34,7 +34,7 @@ import java.util.Queue;
|
|||||||
* and {@link Unpooled#wrappedBuffer(ByteBuffer)} instead of calling the
|
* and {@link Unpooled#wrappedBuffer(ByteBuffer)} instead of calling the
|
||||||
* constructor explicitly.
|
* constructor explicitly.
|
||||||
*/
|
*/
|
||||||
final class UnpooledDirectByteBuf extends AbstractByteBuf {
|
final class UnpooledDirectByteBuf extends AbstractReferenceCountedByteBuf {
|
||||||
|
|
||||||
private final ResourceLeak leak = leakDetector.open(this);
|
private final ResourceLeak leak = leakDetector.open(this);
|
||||||
private final ByteBufAllocator alloc;
|
private final ByteBufAllocator alloc;
|
||||||
@ -134,7 +134,7 @@ final class UnpooledDirectByteBuf extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf capacity(int newCapacity) {
|
public ByteBuf capacity(int newCapacity) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
if (newCapacity < 0 || newCapacity > maxCapacity()) {
|
if (newCapacity < 0 || newCapacity > maxCapacity()) {
|
||||||
throw new IllegalArgumentException("newCapacity: " + newCapacity);
|
throw new IllegalArgumentException("newCapacity: " + newCapacity);
|
||||||
}
|
}
|
||||||
@ -197,37 +197,37 @@ final class UnpooledDirectByteBuf extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte getByte(int index) {
|
public byte getByte(int index) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
return buffer.get(index);
|
return buffer.get(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public short getShort(int index) {
|
public short getShort(int index) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
return buffer.getShort(index);
|
return buffer.getShort(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getUnsignedMedium(int index) {
|
public int getUnsignedMedium(int index) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
return (getByte(index) & 0xff) << 16 | (getByte(index + 1) & 0xff) << 8 | getByte(index + 2) & 0xff;
|
return (getByte(index) & 0xff) << 16 | (getByte(index + 1) & 0xff) << 8 | getByte(index + 2) & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getInt(int index) {
|
public int getInt(int index) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
return buffer.getInt(index);
|
return buffer.getInt(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getLong(int index) {
|
public long getLong(int index) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
return buffer.getLong(index);
|
return buffer.getLong(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
|
public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
if (dst instanceof UnpooledDirectByteBuf) {
|
if (dst instanceof UnpooledDirectByteBuf) {
|
||||||
UnpooledDirectByteBuf bbdst = (UnpooledDirectByteBuf) dst;
|
UnpooledDirectByteBuf bbdst = (UnpooledDirectByteBuf) dst;
|
||||||
ByteBuffer data = bbdst.internalNioBuffer();
|
ByteBuffer data = bbdst.internalNioBuffer();
|
||||||
@ -274,21 +274,21 @@ final class UnpooledDirectByteBuf extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf setByte(int index, int value) {
|
public ByteBuf setByte(int index, int value) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
buffer.put(index, (byte) value);
|
buffer.put(index, (byte) value);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf setShort(int index, int value) {
|
public ByteBuf setShort(int index, int value) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
buffer.putShort(index, (short) value);
|
buffer.putShort(index, (short) value);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf setMedium(int index, int value) {
|
public ByteBuf setMedium(int index, int value) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
setByte(index, (byte) (value >>> 16));
|
setByte(index, (byte) (value >>> 16));
|
||||||
setByte(index + 1, (byte) (value >>> 8));
|
setByte(index + 1, (byte) (value >>> 8));
|
||||||
setByte(index + 2, (byte) value);
|
setByte(index + 2, (byte) value);
|
||||||
@ -297,21 +297,21 @@ final class UnpooledDirectByteBuf extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf setInt(int index, int value) {
|
public ByteBuf setInt(int index, int value) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
buffer.putInt(index, value);
|
buffer.putInt(index, value);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf setLong(int index, long value) {
|
public ByteBuf setLong(int index, long value) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
buffer.putLong(index, value);
|
buffer.putLong(index, value);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
|
public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
if (src instanceof UnpooledDirectByteBuf) {
|
if (src instanceof UnpooledDirectByteBuf) {
|
||||||
UnpooledDirectByteBuf bbsrc = (UnpooledDirectByteBuf) src;
|
UnpooledDirectByteBuf bbsrc = (UnpooledDirectByteBuf) src;
|
||||||
ByteBuffer data = bbsrc.internalNioBuffer();
|
ByteBuffer data = bbsrc.internalNioBuffer();
|
||||||
@ -328,7 +328,7 @@ final class UnpooledDirectByteBuf extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) {
|
public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
ByteBuffer tmpBuf = internalNioBuffer();
|
ByteBuffer tmpBuf = internalNioBuffer();
|
||||||
tmpBuf.clear().position(index).limit(index + length);
|
tmpBuf.clear().position(index).limit(index + length);
|
||||||
tmpBuf.put(src, srcIndex, length);
|
tmpBuf.put(src, srcIndex, length);
|
||||||
@ -337,7 +337,7 @@ final class UnpooledDirectByteBuf extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf setBytes(int index, ByteBuffer src) {
|
public ByteBuf setBytes(int index, ByteBuffer src) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
ByteBuffer tmpBuf = internalNioBuffer();
|
ByteBuffer tmpBuf = internalNioBuffer();
|
||||||
if (src == tmpBuf) {
|
if (src == tmpBuf) {
|
||||||
src = src.duplicate();
|
src = src.duplicate();
|
||||||
@ -350,7 +350,7 @@ final class UnpooledDirectByteBuf extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException {
|
public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -369,7 +369,7 @@ final class UnpooledDirectByteBuf extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBytes(int index, GatheringByteChannel out, int length) throws IOException {
|
public int getBytes(int index, GatheringByteChannel out, int length) throws IOException {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -381,7 +381,7 @@ final class UnpooledDirectByteBuf extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int setBytes(int index, InputStream in, int length) throws IOException {
|
public int setBytes(int index, InputStream in, int length) throws IOException {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
if (buffer.hasArray()) {
|
if (buffer.hasArray()) {
|
||||||
return in.read(buffer.array(), buffer.arrayOffset() + index, length);
|
return in.read(buffer.array(), buffer.arrayOffset() + index, length);
|
||||||
} else {
|
} else {
|
||||||
@ -399,7 +399,7 @@ final class UnpooledDirectByteBuf extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException {
|
public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
ByteBuffer tmpNioBuf = internalNioBuffer();
|
ByteBuffer tmpNioBuf = internalNioBuffer();
|
||||||
tmpNioBuf.clear().position(index).limit(index + length);
|
tmpNioBuf.clear().position(index).limit(index + length);
|
||||||
try {
|
try {
|
||||||
@ -416,7 +416,7 @@ final class UnpooledDirectByteBuf extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuffer nioBuffer(int index, int length) {
|
public ByteBuffer nioBuffer(int index, int length) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
if (index == 0 && length == capacity()) {
|
if (index == 0 && length == capacity()) {
|
||||||
return buffer.duplicate();
|
return buffer.duplicate();
|
||||||
} else {
|
} else {
|
||||||
@ -431,7 +431,7 @@ final class UnpooledDirectByteBuf extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf copy(int index, int length) {
|
public ByteBuf copy(int index, int length) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
ByteBuffer src;
|
ByteBuffer src;
|
||||||
try {
|
try {
|
||||||
src = (ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length);
|
src = (ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length);
|
||||||
@ -456,12 +456,7 @@ final class UnpooledDirectByteBuf extends AbstractByteBuf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFreed() {
|
protected void deallocate() {
|
||||||
return buffer == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void free() {
|
|
||||||
ByteBuffer buffer = this.buffer;
|
ByteBuffer buffer = this.buffer;
|
||||||
if (buffer == null) {
|
if (buffer == null) {
|
||||||
return;
|
return;
|
||||||
@ -478,6 +473,7 @@ final class UnpooledDirectByteBuf extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf suspendIntermediaryDeallocations() {
|
public ByteBuf suspendIntermediaryDeallocations() {
|
||||||
|
ensureAccessible();
|
||||||
if (suspendedDeallocations == null) {
|
if (suspendedDeallocations == null) {
|
||||||
suspendedDeallocations = new ArrayDeque<ByteBuffer>(2);
|
suspendedDeallocations = new ArrayDeque<ByteBuffer>(2);
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ import java.nio.channels.ScatteringByteChannel;
|
|||||||
/**
|
/**
|
||||||
* Big endian Java heap buffer implementation.
|
* Big endian Java heap buffer implementation.
|
||||||
*/
|
*/
|
||||||
final class UnpooledHeapByteBuf extends AbstractByteBuf {
|
final class UnpooledHeapByteBuf extends AbstractReferenceCountedByteBuf {
|
||||||
|
|
||||||
private final ByteBufAllocator alloc;
|
private final ByteBufAllocator alloc;
|
||||||
private byte[] array;
|
private byte[] array;
|
||||||
@ -96,13 +96,13 @@ final class UnpooledHeapByteBuf extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int capacity() {
|
public int capacity() {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
return array.length;
|
return array.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf capacity(int newCapacity) {
|
public ByteBuf capacity(int newCapacity) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
if (newCapacity < 0 || newCapacity > maxCapacity()) {
|
if (newCapacity < 0 || newCapacity > maxCapacity()) {
|
||||||
throw new IllegalArgumentException("newCapacity: " + newCapacity);
|
throw new IllegalArgumentException("newCapacity: " + newCapacity);
|
||||||
}
|
}
|
||||||
@ -136,7 +136,7 @@ final class UnpooledHeapByteBuf extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] array() {
|
public byte[] array() {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,13 +147,13 @@ final class UnpooledHeapByteBuf extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte getByte(int index) {
|
public byte getByte(int index) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
return array[index];
|
return array[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
|
public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
if (dst.hasArray()) {
|
if (dst.hasArray()) {
|
||||||
getBytes(index, dst.array(), dst.arrayOffset() + dstIndex, length);
|
getBytes(index, dst.array(), dst.arrayOffset() + dstIndex, length);
|
||||||
} else {
|
} else {
|
||||||
@ -164,41 +164,41 @@ final class UnpooledHeapByteBuf extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) {
|
public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
System.arraycopy(array, index, dst, dstIndex, length);
|
System.arraycopy(array, index, dst, dstIndex, length);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf getBytes(int index, ByteBuffer dst) {
|
public ByteBuf getBytes(int index, ByteBuffer dst) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
dst.put(array, index, Math.min(capacity() - index, dst.remaining()));
|
dst.put(array, index, Math.min(capacity() - index, dst.remaining()));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException {
|
public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
out.write(array, index, length);
|
out.write(array, index, length);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBytes(int index, GatheringByteChannel out, int length) throws IOException {
|
public int getBytes(int index, GatheringByteChannel out, int length) throws IOException {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
return out.write((ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length));
|
return out.write((ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf setByte(int index, int value) {
|
public ByteBuf setByte(int index, int value) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
array[index] = (byte) value;
|
array[index] = (byte) value;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
|
public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
if (src.hasArray()) {
|
if (src.hasArray()) {
|
||||||
setBytes(index, src.array(), src.arrayOffset() + srcIndex, length);
|
setBytes(index, src.array(), src.arrayOffset() + srcIndex, length);
|
||||||
} else {
|
} else {
|
||||||
@ -209,27 +209,27 @@ final class UnpooledHeapByteBuf extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) {
|
public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
System.arraycopy(src, srcIndex, array, index, length);
|
System.arraycopy(src, srcIndex, array, index, length);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf setBytes(int index, ByteBuffer src) {
|
public ByteBuf setBytes(int index, ByteBuffer src) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
src.get(array, index, src.remaining());
|
src.get(array, index, src.remaining());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int setBytes(int index, InputStream in, int length) throws IOException {
|
public int setBytes(int index, InputStream in, int length) throws IOException {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
return in.read(array, index, length);
|
return in.read(array, index, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException {
|
public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
try {
|
try {
|
||||||
return in.read((ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length));
|
return in.read((ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length));
|
||||||
} catch (ClosedChannelException e) {
|
} catch (ClosedChannelException e) {
|
||||||
@ -244,7 +244,7 @@ final class UnpooledHeapByteBuf extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuffer nioBuffer(int index, int length) {
|
public ByteBuffer nioBuffer(int index, int length) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
return ByteBuffer.wrap(array, index, length);
|
return ByteBuffer.wrap(array, index, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,13 +255,13 @@ final class UnpooledHeapByteBuf extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public short getShort(int index) {
|
public short getShort(int index) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
return (short) (array[index] << 8 | array[index + 1] & 0xFF);
|
return (short) (array[index] << 8 | array[index + 1] & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getUnsignedMedium(int index) {
|
public int getUnsignedMedium(int index) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
return (array[index] & 0xff) << 16 |
|
return (array[index] & 0xff) << 16 |
|
||||||
(array[index + 1] & 0xff) << 8 |
|
(array[index + 1] & 0xff) << 8 |
|
||||||
array[index + 2] & 0xff;
|
array[index + 2] & 0xff;
|
||||||
@ -269,7 +269,7 @@ final class UnpooledHeapByteBuf extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getInt(int index) {
|
public int getInt(int index) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
return (array[index] & 0xff) << 24 |
|
return (array[index] & 0xff) << 24 |
|
||||||
(array[index + 1] & 0xff) << 16 |
|
(array[index + 1] & 0xff) << 16 |
|
||||||
(array[index + 2] & 0xff) << 8 |
|
(array[index + 2] & 0xff) << 8 |
|
||||||
@ -278,7 +278,7 @@ final class UnpooledHeapByteBuf extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getLong(int index) {
|
public long getLong(int index) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
return ((long) array[index] & 0xff) << 56 |
|
return ((long) array[index] & 0xff) << 56 |
|
||||||
((long) array[index + 1] & 0xff) << 48 |
|
((long) array[index + 1] & 0xff) << 48 |
|
||||||
((long) array[index + 2] & 0xff) << 40 |
|
((long) array[index + 2] & 0xff) << 40 |
|
||||||
@ -291,7 +291,7 @@ final class UnpooledHeapByteBuf extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf setShort(int index, int value) {
|
public ByteBuf setShort(int index, int value) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
array[index] = (byte) (value >>> 8);
|
array[index] = (byte) (value >>> 8);
|
||||||
array[index + 1] = (byte) value;
|
array[index + 1] = (byte) value;
|
||||||
return this;
|
return this;
|
||||||
@ -299,7 +299,7 @@ final class UnpooledHeapByteBuf extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf setMedium(int index, int value) {
|
public ByteBuf setMedium(int index, int value) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
array[index] = (byte) (value >>> 16);
|
array[index] = (byte) (value >>> 16);
|
||||||
array[index + 1] = (byte) (value >>> 8);
|
array[index + 1] = (byte) (value >>> 8);
|
||||||
array[index + 2] = (byte) value;
|
array[index + 2] = (byte) value;
|
||||||
@ -308,7 +308,7 @@ final class UnpooledHeapByteBuf extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf setInt(int index, int value) {
|
public ByteBuf setInt(int index, int value) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
array[index] = (byte) (value >>> 24);
|
array[index] = (byte) (value >>> 24);
|
||||||
array[index + 1] = (byte) (value >>> 16);
|
array[index + 1] = (byte) (value >>> 16);
|
||||||
array[index + 2] = (byte) (value >>> 8);
|
array[index + 2] = (byte) (value >>> 8);
|
||||||
@ -318,7 +318,7 @@ final class UnpooledHeapByteBuf extends AbstractByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf setLong(int index, long value) {
|
public ByteBuf setLong(int index, long value) {
|
||||||
checkUnfreed();
|
ensureAccessible();
|
||||||
array[index] = (byte) (value >>> 56);
|
array[index] = (byte) (value >>> 56);
|
||||||
array[index + 1] = (byte) (value >>> 48);
|
array[index + 1] = (byte) (value >>> 48);
|
||||||
array[index + 2] = (byte) (value >>> 40);
|
array[index + 2] = (byte) (value >>> 40);
|
||||||
@ -347,12 +347,7 @@ final class UnpooledHeapByteBuf extends AbstractByteBuf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFreed() {
|
protected void deallocate() {
|
||||||
return array == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void free() {
|
|
||||||
array = null;
|
array = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ import java.util.Random;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static io.netty.buffer.Unpooled.*;
|
import static io.netty.buffer.Unpooled.*;
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,8 +63,16 @@ public abstract class AbstractByteBufTest {
|
|||||||
@After
|
@After
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
if (buffer != null) {
|
if (buffer != null) {
|
||||||
|
if (buffer.unwrap() == null) {
|
||||||
|
assertThat(buffer.release(), is(true));
|
||||||
|
assertThat(buffer.refCnt(), is(0));
|
||||||
|
} else {
|
||||||
|
assertThat(buffer.release(), is(false));
|
||||||
|
assertThat(buffer.refCnt(), is(1));
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
buffer.free();
|
buffer.release();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// Ignore.
|
// Ignore.
|
||||||
}
|
}
|
||||||
@ -872,8 +881,8 @@ public abstract class AbstractByteBufTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
value.free();
|
value.release();
|
||||||
expectedValue.free();
|
expectedValue.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -1049,7 +1058,7 @@ public abstract class AbstractByteBufTest {
|
|||||||
assertEquals(0, value.writerIndex());
|
assertEquals(0, value.writerIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
value.free();
|
value.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -1090,7 +1099,7 @@ public abstract class AbstractByteBufTest {
|
|||||||
assertEquals(valueOffset + BLOCK_SIZE, value.writerIndex());
|
assertEquals(valueOffset + BLOCK_SIZE, value.writerIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
value.free();
|
value.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -1623,8 +1632,8 @@ public abstract class AbstractByteBufTest {
|
|||||||
assertFalse(set.contains(elemB));
|
assertFalse(set.contains(elemB));
|
||||||
assertEquals(0, set.size());
|
assertEquals(0, set.size());
|
||||||
|
|
||||||
elemB.free();
|
elemB.release();
|
||||||
elemBCopy.free();
|
elemBCopy.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test case for https://github.com/netty/netty/issues/325
|
// Test case for https://github.com/netty/netty/issues/325
|
||||||
|
@ -52,7 +52,7 @@ public class UnpooledTest {
|
|||||||
assertEquals(12 + 512, buffer.readableBytes());
|
assertEquals(12 + 512, buffer.readableBytes());
|
||||||
assertEquals(2, buffer.nioBufferCount());
|
assertEquals(2, buffer.nioBufferCount());
|
||||||
|
|
||||||
buffer.free();
|
buffer.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -160,11 +160,8 @@ public class UnpooledTest {
|
|||||||
@Test
|
@Test
|
||||||
public void shouldReturnEmptyBufferWhenLengthIsZero() {
|
public void shouldReturnEmptyBufferWhenLengthIsZero() {
|
||||||
assertSame(EMPTY_BUFFER, wrappedBuffer(new byte[0]));
|
assertSame(EMPTY_BUFFER, wrappedBuffer(new byte[0]));
|
||||||
assertSame(EMPTY_BUFFER, wrappedBuffer(new byte[0]).order(LITTLE_ENDIAN));
|
|
||||||
assertSame(EMPTY_BUFFER, wrappedBuffer(new byte[8], 0, 0));
|
assertSame(EMPTY_BUFFER, wrappedBuffer(new byte[8], 0, 0));
|
||||||
assertSame(EMPTY_BUFFER, wrappedBuffer(new byte[8], 0, 0).order(LITTLE_ENDIAN));
|
|
||||||
assertSame(EMPTY_BUFFER, wrappedBuffer(new byte[8], 8, 0));
|
assertSame(EMPTY_BUFFER, wrappedBuffer(new byte[8], 8, 0));
|
||||||
assertSame(EMPTY_BUFFER, wrappedBuffer(new byte[8], 8, 0).order(LITTLE_ENDIAN));
|
|
||||||
assertSame(EMPTY_BUFFER, wrappedBuffer(ByteBuffer.allocateDirect(0)));
|
assertSame(EMPTY_BUFFER, wrappedBuffer(ByteBuffer.allocateDirect(0)));
|
||||||
assertSame(EMPTY_BUFFER, wrappedBuffer(EMPTY_BUFFER));
|
assertSame(EMPTY_BUFFER, wrappedBuffer(EMPTY_BUFFER));
|
||||||
assertSame(EMPTY_BUFFER, wrappedBuffer(new byte[0][]));
|
assertSame(EMPTY_BUFFER, wrappedBuffer(new byte[0][]));
|
||||||
@ -177,11 +174,8 @@ public class UnpooledTest {
|
|||||||
assertSame(EMPTY_BUFFER, wrappedBuffer(buffer(0), buffer(0)));
|
assertSame(EMPTY_BUFFER, wrappedBuffer(buffer(0), buffer(0)));
|
||||||
|
|
||||||
assertSame(EMPTY_BUFFER, copiedBuffer(new byte[0]));
|
assertSame(EMPTY_BUFFER, copiedBuffer(new byte[0]));
|
||||||
assertSame(EMPTY_BUFFER, copiedBuffer(new byte[0]).order(LITTLE_ENDIAN));
|
|
||||||
assertSame(EMPTY_BUFFER, copiedBuffer(new byte[8], 0, 0));
|
assertSame(EMPTY_BUFFER, copiedBuffer(new byte[8], 0, 0));
|
||||||
assertSame(EMPTY_BUFFER, copiedBuffer(new byte[8], 0, 0).order(LITTLE_ENDIAN));
|
|
||||||
assertSame(EMPTY_BUFFER, copiedBuffer(new byte[8], 8, 0));
|
assertSame(EMPTY_BUFFER, copiedBuffer(new byte[8], 8, 0));
|
||||||
assertSame(EMPTY_BUFFER, copiedBuffer(new byte[8], 8, 0).order(LITTLE_ENDIAN));
|
|
||||||
assertSame(EMPTY_BUFFER, copiedBuffer(ByteBuffer.allocateDirect(0)));
|
assertSame(EMPTY_BUFFER, copiedBuffer(ByteBuffer.allocateDirect(0)));
|
||||||
assertSame(EMPTY_BUFFER, copiedBuffer(EMPTY_BUFFER));
|
assertSame(EMPTY_BUFFER, copiedBuffer(EMPTY_BUFFER));
|
||||||
assertSame(EMPTY_BUFFER, copiedBuffer(new byte[0][]));
|
assertSame(EMPTY_BUFFER, copiedBuffer(new byte[0][]));
|
||||||
|
@ -48,13 +48,28 @@ public class DefaultFullHttpRequest extends DefaultHttpRequest implements FullHt
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFreed() {
|
public int refCnt() {
|
||||||
return content.isFreed();
|
return content.refCnt();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void free() {
|
public void retain() {
|
||||||
content.free();
|
content.retain();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void retain(int increment) {
|
||||||
|
content.retain(increment);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean release() {
|
||||||
|
return content.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean release(int decrement) {
|
||||||
|
return content.release(decrement);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -50,13 +50,28 @@ public class DefaultFullHttpResponse extends DefaultHttpResponse implements Full
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFreed() {
|
public int refCnt() {
|
||||||
return content.isFreed();
|
return content.refCnt();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void free() {
|
public void retain() {
|
||||||
content.free();
|
content.retain();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void retain(int increment) {
|
||||||
|
content.retain(increment);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean release() {
|
||||||
|
return content.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean release(int decrement) {
|
||||||
|
return content.release(decrement);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -41,17 +41,32 @@ public class DefaultHttpContent extends DefaultHttpObject implements HttpContent
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpContent copy() {
|
public HttpContent copy() {
|
||||||
return new DefaultHttpContent(data().copy());
|
return new DefaultHttpContent(content.copy());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFreed() {
|
public int refCnt() {
|
||||||
return content.isFreed();
|
return content.refCnt();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void free() {
|
public void retain() {
|
||||||
content.free();
|
content.retain();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void retain(int increment) {
|
||||||
|
content.retain(increment);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean release() {
|
||||||
|
return content.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean release(int decrement) {
|
||||||
|
return content.release(decrement);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -156,7 +156,7 @@ public class HttpObjectAggregator extends MessageToMessageDecoder<HttpObject> {
|
|||||||
CompositeByteBuf content = (CompositeByteBuf) currentMessage.data();
|
CompositeByteBuf content = (CompositeByteBuf) currentMessage.data();
|
||||||
|
|
||||||
if (content.readableBytes() > maxContentLength - chunk.data().readableBytes()) {
|
if (content.readableBytes() > maxContentLength - chunk.data().readableBytes()) {
|
||||||
chunk.free();
|
chunk.release();
|
||||||
// TODO: Respond with 413 Request Entity Too Large
|
// TODO: Respond with 413 Request Entity Too Large
|
||||||
// and discard the traffic or close the connection.
|
// and discard the traffic or close the connection.
|
||||||
// No need to notify the upstream handlers - just log.
|
// No need to notify the upstream handlers - just log.
|
||||||
@ -171,7 +171,7 @@ public class HttpObjectAggregator extends MessageToMessageDecoder<HttpObject> {
|
|||||||
content.addComponent(chunk.data());
|
content.addComponent(chunk.data());
|
||||||
content.writerIndex(content.writerIndex() + chunk.data().readableBytes());
|
content.writerIndex(content.writerIndex() + chunk.data().readableBytes());
|
||||||
} else {
|
} else {
|
||||||
chunk.free();
|
chunk.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean last;
|
final boolean last;
|
||||||
|
@ -55,13 +55,24 @@ public interface LastHttpContent extends HttpContent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFreed() {
|
public int refCnt() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void retain() { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void retain(int increment) { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean release() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void free() {
|
public boolean release(int decrement) {
|
||||||
// NOOP
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -352,13 +352,4 @@ public abstract class AbstractDiskHttpData extends AbstractHttpData {
|
|||||||
public File getFile() throws IOException {
|
public File getFile() throws IOException {
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFreed() {
|
|
||||||
if (file == null || !file.exists()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.http.multipart;
|
package io.netty.handler.codec.http.multipart;
|
||||||
|
|
||||||
|
import io.netty.buffer.AbstractReferenceCounted;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.ChannelException;
|
import io.netty.channel.ChannelException;
|
||||||
import io.netty.handler.codec.http.HttpConstants;
|
import io.netty.handler.codec.http.HttpConstants;
|
||||||
@ -25,7 +26,7 @@ import java.nio.charset.Charset;
|
|||||||
/**
|
/**
|
||||||
* Abstract HttpData implementation
|
* Abstract HttpData implementation
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractHttpData implements HttpData {
|
public abstract class AbstractHttpData extends AbstractReferenceCounted implements HttpData {
|
||||||
|
|
||||||
protected final String name;
|
protected final String name;
|
||||||
protected long definedSize;
|
protected long definedSize;
|
||||||
@ -110,8 +111,7 @@ public abstract class AbstractHttpData implements HttpData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void free() {
|
protected void deallocate() {
|
||||||
delete();
|
delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,7 @@ public abstract class AbstractMemoryHttpData extends AbstractHttpData {
|
|||||||
@Override
|
@Override
|
||||||
public byte[] get() {
|
public byte[] get() {
|
||||||
if (byteBuf == null) {
|
if (byteBuf == null) {
|
||||||
return new byte[0];
|
return EMPTY_BUFFER.array();
|
||||||
}
|
}
|
||||||
byte[] array = new byte[byteBuf.readableBytes()];
|
byte[] array = new byte[byteBuf.readableBytes()];
|
||||||
byteBuf.getBytes(byteBuf.readerIndex(), array);
|
byteBuf.getBytes(byteBuf.readerIndex(), array);
|
||||||
@ -226,9 +226,4 @@ public abstract class AbstractMemoryHttpData extends AbstractHttpData {
|
|||||||
public File getFile() throws IOException {
|
public File getFile() throws IOException {
|
||||||
throw new IOException("Not represented by a file");
|
throw new IOException("Not represented by a file");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFreed() {
|
|
||||||
return data().isFreed();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -210,12 +210,27 @@ public class MixedAttribute implements Attribute {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void free() {
|
public int refCnt() {
|
||||||
attribute.free();
|
return attribute.refCnt();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFreed() {
|
public void retain() {
|
||||||
return attribute.isFreed();
|
attribute.retain();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void retain(int increment) {
|
||||||
|
attribute.retain(increment);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean release() {
|
||||||
|
return attribute.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean release(int decrement) {
|
||||||
|
return attribute.release(decrement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import java.nio.charset.Charset;
|
|||||||
* Mixed implementation using both in Memory and in File with a limit of size
|
* Mixed implementation using both in Memory and in File with a limit of size
|
||||||
*/
|
*/
|
||||||
public class MixedFileUpload implements FileUpload {
|
public class MixedFileUpload implements FileUpload {
|
||||||
|
|
||||||
private FileUpload fileUpload;
|
private FileUpload fileUpload;
|
||||||
|
|
||||||
private final long limitSize;
|
private final long limitSize;
|
||||||
@ -235,12 +236,27 @@ public class MixedFileUpload implements FileUpload {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void free() {
|
public int refCnt() {
|
||||||
fileUpload.free();
|
return fileUpload.refCnt();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFreed() {
|
public void retain() {
|
||||||
return fileUpload.isFreed();
|
fileUpload.retain();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void retain(int increment) {
|
||||||
|
fileUpload.retain(increment);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean release() {
|
||||||
|
return fileUpload.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean release(int decrement) {
|
||||||
|
return fileUpload.release(decrement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ public class DefaultSpdyDataFrame extends DefaultByteBufHolder implements SpdyDa
|
|||||||
buf.append(streamId);
|
buf.append(streamId);
|
||||||
buf.append(StringUtil.NEWLINE);
|
buf.append(StringUtil.NEWLINE);
|
||||||
buf.append("--> Size = ");
|
buf.append("--> Size = ");
|
||||||
if (isFreed()) {
|
if (refCnt() <= 0) {
|
||||||
buf.append("(freed)");
|
buf.append("(freed)");
|
||||||
} else {
|
} else {
|
||||||
buf.append(data().readableBytes());
|
buf.append(data().readableBytes());
|
||||||
|
@ -72,7 +72,7 @@ public abstract class SpdyOrHttpChooser extends ChannelDuplexHandler implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void freeInboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
public void freeInboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
||||||
ctx.inboundByteBuffer().free();
|
ctx.inboundByteBuffer().release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -92,7 +92,7 @@ public class SpdySessionHandler
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void freeInboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
public void freeInboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
||||||
ctx.inboundByteBuffer().free();
|
ctx.inboundByteBuffer().release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -102,7 +102,7 @@ public class SpdySessionHandler
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void freeOutboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
public void freeOutboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
||||||
ctx.outboundMessageBuffer().free();
|
ctx.outboundMessageBuffer().release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -150,7 +150,7 @@ public class WebSocketServerProtocolHandlerTest {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void freeOutboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
public void freeOutboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
||||||
ctx.outboundMessageBuffer().free();
|
ctx.outboundMessageBuffer().release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -174,10 +174,10 @@ public abstract class MessageToMessageCodec<INBOUND_IN, OUTBOUND_IN>
|
|||||||
protected abstract Object decode(ChannelHandlerContext ctx, INBOUND_IN msg) throws Exception;
|
protected abstract Object decode(ChannelHandlerContext ctx, INBOUND_IN msg) throws Exception;
|
||||||
|
|
||||||
protected void freeInboundMessage(INBOUND_IN msg) throws Exception {
|
protected void freeInboundMessage(INBOUND_IN msg) throws Exception {
|
||||||
BufUtil.free(msg);
|
BufUtil.release(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void freeOutboundMessage(OUTBOUND_IN msg) throws Exception {
|
protected void freeOutboundMessage(OUTBOUND_IN msg) throws Exception {
|
||||||
BufUtil.free(msg);
|
BufUtil.release(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -879,12 +879,27 @@ final class ReplayingDecoderBuffer implements ByteBuf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFreed() {
|
public int refCnt() {
|
||||||
return buffer.isFreed();
|
return buffer.refCnt();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void free() {
|
public void retain() {
|
||||||
|
throw new UnreplayableOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void retain(int increment) {
|
||||||
|
throw new UnreplayableOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean release() {
|
||||||
|
throw new UnreplayableOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean release(int decrement) {
|
||||||
throw new UnreplayableOperationException();
|
throw new UnreplayableOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,9 +47,8 @@ public class ByteArrayDecoderTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDecodeEmpty() {
|
public void testDecodeEmpty() {
|
||||||
byte[] b = new byte[0];
|
ch.writeInbound(EMPTY_BUFFER);
|
||||||
ch.writeInbound(wrappedBuffer(b));
|
assertThat((byte[]) ch.readInbound(), is(new byte[0]));
|
||||||
assertThat((byte[]) ch.readInbound(), is(b));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -32,7 +32,8 @@ public class DiscardClientHandler extends ChannelInboundByteHandlerAdapter {
|
|||||||
private static final Logger logger = Logger.getLogger(
|
private static final Logger logger = Logger.getLogger(
|
||||||
DiscardClientHandler.class.getName());
|
DiscardClientHandler.class.getName());
|
||||||
|
|
||||||
private final byte[] content;
|
private final int messageSize;
|
||||||
|
private ByteBuf content;
|
||||||
private ChannelHandlerContext ctx;
|
private ChannelHandlerContext ctx;
|
||||||
|
|
||||||
public DiscardClientHandler(int messageSize) {
|
public DiscardClientHandler(int messageSize) {
|
||||||
@ -40,13 +41,17 @@ public class DiscardClientHandler extends ChannelInboundByteHandlerAdapter {
|
|||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"messageSize: " + messageSize);
|
"messageSize: " + messageSize);
|
||||||
}
|
}
|
||||||
content = new byte[messageSize];
|
this.messageSize = messageSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void channelActive(ChannelHandlerContext ctx)
|
public void channelActive(ChannelHandlerContext ctx)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
|
|
||||||
|
// Initialize the message.
|
||||||
|
content = ctx.alloc().directBuffer(messageSize).writeZero(messageSize);
|
||||||
|
|
||||||
// Send the initial messages.
|
// Send the initial messages.
|
||||||
generateTraffic();
|
generateTraffic();
|
||||||
}
|
}
|
||||||
@ -75,7 +80,7 @@ public class DiscardClientHandler extends ChannelInboundByteHandlerAdapter {
|
|||||||
// Fill the outbound buffer up to 64KiB
|
// Fill the outbound buffer up to 64KiB
|
||||||
ByteBuf out = ctx.nextOutboundByteBuffer();
|
ByteBuf out = ctx.nextOutboundByteBuffer();
|
||||||
while (out.readableBytes() < 65536) {
|
while (out.readableBytes() < 65536) {
|
||||||
out.writeBytes(content);
|
out.writeBytes(content, 0, content.readableBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush the outbound buffer to the socket.
|
// Flush the outbound buffer to the socket.
|
||||||
|
@ -30,6 +30,13 @@ public class DiscardServerHandler extends ChannelInboundByteHandlerAdapter {
|
|||||||
private static final Logger logger = Logger.getLogger(
|
private static final Logger logger = Logger.getLogger(
|
||||||
DiscardServerHandler.class.getName());
|
DiscardServerHandler.class.getName());
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf newInboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
||||||
|
// Use direct buffer if possible.
|
||||||
|
// If you are going to use a heap buffer, you don't need to override this method.
|
||||||
|
return ctx.alloc().ioBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void inboundBufferUpdated(ChannelHandlerContext ctx, ByteBuf in)
|
public void inboundBufferUpdated(ChannelHandlerContext ctx, ByteBuf in)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
@ -48,6 +48,13 @@ public class EchoClientHandler extends ChannelInboundByteHandlerAdapter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf newInboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
||||||
|
// Use direct buffer if possible.
|
||||||
|
// If you are going to use a heap buffer, you don't need to override this method.
|
||||||
|
return ctx.alloc().ioBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void channelActive(ChannelHandlerContext ctx) {
|
public void channelActive(ChannelHandlerContext ctx) {
|
||||||
ctx.write(firstMessage);
|
ctx.write(firstMessage);
|
||||||
|
@ -32,6 +32,13 @@ public class EchoServerHandler extends ChannelInboundByteHandlerAdapter {
|
|||||||
private static final Logger logger = Logger.getLogger(
|
private static final Logger logger = Logger.getLogger(
|
||||||
EchoServerHandler.class.getName());
|
EchoServerHandler.class.getName());
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf newInboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
||||||
|
// Use direct buffer if possible.
|
||||||
|
// If you are going to use a heap buffer, you don't need to override this method.
|
||||||
|
return ctx.alloc().ioBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void inboundBufferUpdated(ChannelHandlerContext ctx, ByteBuf in) {
|
public void inboundBufferUpdated(ChannelHandlerContext ctx, ByteBuf in) {
|
||||||
ByteBuf out = ctx.nextOutboundByteBuffer();
|
ByteBuf out = ctx.nextOutboundByteBuffer();
|
||||||
|
@ -118,7 +118,7 @@ public class ByteLoggingHandler
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void freeInboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
public void freeInboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
||||||
ctx.inboundByteBuffer().free();
|
ctx.inboundByteBuffer().release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -133,7 +133,7 @@ public class ByteLoggingHandler
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void freeOutboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
public void freeOutboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
||||||
ctx.outboundByteBuffer().free();
|
ctx.outboundByteBuffer().release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -388,7 +388,7 @@ public class SslHandler
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void freeInboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
public void freeInboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
||||||
ctx.inboundByteBuffer().free();
|
ctx.inboundByteBuffer().release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -403,7 +403,7 @@ public class SslHandler
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void freeOutboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
public void freeOutboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
||||||
ctx.outboundByteBuffer().free();
|
ctx.outboundByteBuffer().release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -98,7 +98,7 @@ public class ChunkedWriteHandler
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void freeOutboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
public void freeOutboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
||||||
queue.free();
|
queue.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isWritable() {
|
private boolean isWritable() {
|
||||||
|
@ -51,7 +51,7 @@ public class ByteBufAllocatorBenchmark extends DefaultBenchmark {
|
|||||||
@Override
|
@Override
|
||||||
protected void tearDown() throws Exception {
|
protected void tearDown() throws Exception {
|
||||||
for (ByteBuf b: queue) {
|
for (ByteBuf b: queue) {
|
||||||
b.free();
|
b.release();
|
||||||
}
|
}
|
||||||
queue.clear();
|
queue.clear();
|
||||||
}
|
}
|
||||||
@ -63,7 +63,7 @@ public class ByteBufAllocatorBenchmark extends DefaultBenchmark {
|
|||||||
|
|
||||||
for (int i = 0; i < reps; i ++) {
|
for (int i = 0; i < reps; i ++) {
|
||||||
queue.add(alloc.buffer(size));
|
queue.add(alloc.buffer(size));
|
||||||
queue.removeFirst().free();
|
queue.removeFirst().release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ package io.netty.testsuite.transport.socket;
|
|||||||
|
|
||||||
import io.netty.bootstrap.Bootstrap;
|
import io.netty.bootstrap.Bootstrap;
|
||||||
import io.netty.bootstrap.ServerBootstrap;
|
import io.netty.bootstrap.ServerBootstrap;
|
||||||
|
import io.netty.buffer.BufUtil;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
@ -234,6 +235,7 @@ public class SocketSpdyEchoTest extends AbstractSocketTest {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
|
public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||||
|
BufUtil.retain(msg);
|
||||||
ctx.write(msg);
|
ctx.write(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ public final class SctpMessage extends DefaultByteBufHolder {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
if (isFreed()) {
|
if (refCnt() <= 0) {
|
||||||
return "SctpFrame{" +
|
return "SctpFrame{" +
|
||||||
"streamIdentifier=" + streamIdentifier + ", protocolIdentifier=" + protocolIdentifier +
|
"streamIdentifier=" + streamIdentifier + ", protocolIdentifier=" + protocolIdentifier +
|
||||||
", data=(FREED)}";
|
", data=(FREED)}";
|
||||||
|
@ -27,12 +27,12 @@ import io.netty.channel.ChannelException;
|
|||||||
import io.netty.channel.ChannelFuture;
|
import io.netty.channel.ChannelFuture;
|
||||||
import io.netty.channel.ChannelMetadata;
|
import io.netty.channel.ChannelMetadata;
|
||||||
import io.netty.channel.ChannelPromise;
|
import io.netty.channel.ChannelPromise;
|
||||||
import io.netty.channel.sctp.SctpServerChannel;
|
|
||||||
import io.netty.channel.nio.AbstractNioMessageChannel;
|
import io.netty.channel.nio.AbstractNioMessageChannel;
|
||||||
import io.netty.channel.sctp.DefaultSctpChannelConfig;
|
import io.netty.channel.sctp.DefaultSctpChannelConfig;
|
||||||
import io.netty.channel.sctp.SctpChannelConfig;
|
import io.netty.channel.sctp.SctpChannelConfig;
|
||||||
import io.netty.channel.sctp.SctpMessage;
|
import io.netty.channel.sctp.SctpMessage;
|
||||||
import io.netty.channel.sctp.SctpNotificationHandler;
|
import io.netty.channel.sctp.SctpNotificationHandler;
|
||||||
|
import io.netty.channel.sctp.SctpServerChannel;
|
||||||
import io.netty.logging.InternalLogger;
|
import io.netty.logging.InternalLogger;
|
||||||
import io.netty.logging.InternalLoggerFactory;
|
import io.netty.logging.InternalLoggerFactory;
|
||||||
|
|
||||||
@ -288,7 +288,7 @@ public class NioSctpChannel extends AbstractNioMessageChannel implements io.nett
|
|||||||
throw new ChannelException(cause);
|
throw new ChannelException(cause);
|
||||||
} finally {
|
} finally {
|
||||||
if (free) {
|
if (free) {
|
||||||
buffer.free();
|
buffer.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -333,7 +333,7 @@ public class NioSctpChannel extends AbstractNioMessageChannel implements io.nett
|
|||||||
buf.remove();
|
buf.remove();
|
||||||
|
|
||||||
// packet was written free up buffer
|
// packet was written free up buffer
|
||||||
packet.free();
|
packet.release();
|
||||||
|
|
||||||
if (buf.isEmpty()) {
|
if (buf.isEmpty()) {
|
||||||
// Wrote the outbound buffer completely - clear OP_WRITE.
|
// Wrote the outbound buffer completely - clear OP_WRITE.
|
||||||
|
@ -27,12 +27,12 @@ import io.netty.channel.ChannelException;
|
|||||||
import io.netty.channel.ChannelFuture;
|
import io.netty.channel.ChannelFuture;
|
||||||
import io.netty.channel.ChannelMetadata;
|
import io.netty.channel.ChannelMetadata;
|
||||||
import io.netty.channel.ChannelPromise;
|
import io.netty.channel.ChannelPromise;
|
||||||
import io.netty.channel.sctp.SctpServerChannel;
|
|
||||||
import io.netty.channel.oio.AbstractOioMessageChannel;
|
import io.netty.channel.oio.AbstractOioMessageChannel;
|
||||||
import io.netty.channel.sctp.DefaultSctpChannelConfig;
|
import io.netty.channel.sctp.DefaultSctpChannelConfig;
|
||||||
import io.netty.channel.sctp.SctpChannelConfig;
|
import io.netty.channel.sctp.SctpChannelConfig;
|
||||||
import io.netty.channel.sctp.SctpMessage;
|
import io.netty.channel.sctp.SctpMessage;
|
||||||
import io.netty.channel.sctp.SctpNotificationHandler;
|
import io.netty.channel.sctp.SctpNotificationHandler;
|
||||||
|
import io.netty.channel.sctp.SctpServerChannel;
|
||||||
import io.netty.logging.InternalLogger;
|
import io.netty.logging.InternalLogger;
|
||||||
import io.netty.logging.InternalLoggerFactory;
|
import io.netty.logging.InternalLoggerFactory;
|
||||||
|
|
||||||
@ -209,7 +209,7 @@ public class OioSctpChannel extends AbstractOioMessageChannel
|
|||||||
throw new ChannelException(cause);
|
throw new ChannelException(cause);
|
||||||
} finally {
|
} finally {
|
||||||
if (free) {
|
if (free) {
|
||||||
buffer.free();
|
buffer.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -252,7 +252,7 @@ public class OioSctpChannel extends AbstractOioMessageChannel
|
|||||||
|
|
||||||
ch.send(nioData, mi);
|
ch.send(nioData, mi);
|
||||||
} finally {
|
} finally {
|
||||||
packet.free();
|
packet.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
writableKeys.clear();
|
writableKeys.clear();
|
||||||
|
@ -154,7 +154,7 @@ public class NioUdtMessageConnectorChannel extends AbstractNioMessageChannel
|
|||||||
maximumMessageSize);
|
maximumMessageSize);
|
||||||
|
|
||||||
if (receivedMessageSize <= 0) {
|
if (receivedMessageSize <= 0) {
|
||||||
byteBuf.free();
|
byteBuf.release();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,7 +216,7 @@ public class NioUdtMessageConnectorChannel extends AbstractNioMessageChannel
|
|||||||
|
|
||||||
messageQueue.remove();
|
messageQueue.remove();
|
||||||
|
|
||||||
message.free();
|
message.release();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,6 @@ public class EchoMessageHandler extends
|
|||||||
}
|
}
|
||||||
|
|
||||||
message = new UdtMessage(byteBuf);
|
message = new UdtMessage(byteBuf);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -67,24 +66,17 @@ public class EchoMessageHandler extends
|
|||||||
final MessageBuf<Object> out = ctx.nextOutboundMessageBuffer();
|
final MessageBuf<Object> out = ctx.nextOutboundMessageBuffer();
|
||||||
|
|
||||||
out.add(message);
|
out.add(message);
|
||||||
|
|
||||||
ctx.flush();
|
ctx.flush();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exceptionCaught(final ChannelHandlerContext ctx,
|
public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable e) {
|
||||||
final Throwable e) {
|
log.error("exception", e);
|
||||||
|
|
||||||
log.error("exception : {}", e.getMessage());
|
|
||||||
|
|
||||||
ctx.close();
|
ctx.close();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void messageReceived(final ChannelHandlerContext ctx,
|
protected void messageReceived(final ChannelHandlerContext ctx, final UdtMessage message) throws Exception {
|
||||||
final UdtMessage message) throws Exception {
|
|
||||||
|
|
||||||
final ByteBuf byteBuf = message.data();
|
final ByteBuf byteBuf = message.data();
|
||||||
|
|
||||||
@ -94,10 +86,8 @@ public class EchoMessageHandler extends
|
|||||||
|
|
||||||
final MessageBuf<Object> out = ctx.nextOutboundMessageBuffer();
|
final MessageBuf<Object> out = ctx.nextOutboundMessageBuffer();
|
||||||
|
|
||||||
|
message.retain();
|
||||||
out.add(message);
|
out.add(message);
|
||||||
|
|
||||||
ctx.flush();
|
ctx.flush();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -285,7 +285,7 @@ public final class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, Se
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void freeInboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
public void freeInboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
||||||
ctx.inboundMessageBuffer().free();
|
ctx.inboundMessageBuffer().release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ public abstract class ChannelInboundByteHandlerAdapter
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void freeInboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
public void freeInboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
||||||
ctx.inboundByteBuffer().free();
|
ctx.inboundByteBuffer().release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -71,7 +71,7 @@ public abstract class ChannelInboundMessageHandlerAdapter<I>
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void freeInboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
public void freeInboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
||||||
ctx.inboundMessageBuffer().free();
|
ctx.inboundMessageBuffer().release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -178,6 +178,6 @@ public abstract class ChannelInboundMessageHandlerAdapter<I>
|
|||||||
* just pass-through the input message or need it for later usage.
|
* just pass-through the input message or need it for later usage.
|
||||||
*/
|
*/
|
||||||
protected void freeInboundMessage(I msg) throws Exception {
|
protected void freeInboundMessage(I msg) throws Exception {
|
||||||
BufUtil.free(msg);
|
BufUtil.release(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ public abstract class ChannelOutboundByteHandlerAdapter
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void freeOutboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
public void freeOutboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
||||||
ctx.outboundByteBuffer().free();
|
ctx.outboundByteBuffer().release();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -64,7 +64,7 @@ public abstract class ChannelOutboundMessageHandlerAdapter<I>
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void freeOutboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
public void freeOutboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
||||||
ctx.outboundMessageBuffer().free();
|
ctx.outboundMessageBuffer().release();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -179,6 +179,6 @@ public abstract class ChannelOutboundMessageHandlerAdapter<I>
|
|||||||
* just pass-through the input message or need it for later usage.
|
* just pass-through the input message or need it for later usage.
|
||||||
*/
|
*/
|
||||||
protected void freeOutboundMessage(I msg) throws Exception {
|
protected void freeOutboundMessage(I msg) throws Exception {
|
||||||
BufUtil.free(msg);
|
BufUtil.release(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1695,7 +1695,7 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
|
|||||||
try {
|
try {
|
||||||
out.writeBytes(data);
|
out.writeBytes(data);
|
||||||
} finally {
|
} finally {
|
||||||
data.free();
|
data.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,8 @@ package io.netty.channel;
|
|||||||
|
|
||||||
import io.netty.buffer.Buf;
|
import io.netty.buffer.Buf;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Freeable;
|
|
||||||
import io.netty.buffer.MessageBuf;
|
import io.netty.buffer.MessageBuf;
|
||||||
|
import io.netty.buffer.ReferenceCounted;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.channel.Channel.Unsafe;
|
import io.netty.channel.Channel.Unsafe;
|
||||||
import io.netty.logging.InternalLogger;
|
import io.netty.logging.InternalLogger;
|
||||||
@ -1125,8 +1125,8 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void freeInboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
public void freeInboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
||||||
byteSink.free();
|
byteSink.release();
|
||||||
msgSink.free();
|
msgSink.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1148,8 +1148,8 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m instanceof Freeable) {
|
if (m instanceof ReferenceCounted) {
|
||||||
((Freeable) m).free();
|
((ReferenceCounted) m).release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logger.warn(
|
logger.warn(
|
||||||
@ -1262,8 +1262,8 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void freeOutboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
public final void freeOutboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
||||||
msgSink.free();
|
msgSink.release();
|
||||||
byteSink.free();
|
byteSink.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1290,8 +1290,8 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
|||||||
discardedMessages ++;
|
discardedMessages ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m instanceof Freeable) {
|
if (m instanceof ReferenceCounted) {
|
||||||
((Freeable) m).free();
|
((ReferenceCounted) m).release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ public final class DatagramPacket extends DefaultByteBufHolder {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
if (isFreed()) {
|
if (refCnt() <= 0) {
|
||||||
return "DatagramPacket{remoteAddress=" + remoteAddress().toString() +
|
return "DatagramPacket{remoteAddress=" + remoteAddress().toString() +
|
||||||
", data=(FREED)}";
|
", data=(FREED)}";
|
||||||
}
|
}
|
||||||
|
@ -254,7 +254,7 @@ public class AioSocketChannel extends AbstractAioChannel implements SocketChanne
|
|||||||
try {
|
try {
|
||||||
if (buf.isReadable()) {
|
if (buf.isReadable()) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (buf.isFreed()) {
|
if (buf.refCnt() <= 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Ensure the readerIndex of the buffer is 0 before beginning an async write.
|
// Ensure the readerIndex of the buffer is 0 before beginning an async write.
|
||||||
@ -370,7 +370,7 @@ public class AioSocketChannel extends AbstractAioChannel implements SocketChanne
|
|||||||
channel.writeInProgress = false;
|
channel.writeInProgress = false;
|
||||||
|
|
||||||
ByteBuf buf = channel.unsafe().directOutboundContext().outboundByteBuffer();
|
ByteBuf buf = channel.unsafe().directOutboundContext().outboundByteBuffer();
|
||||||
if (buf.isFreed()) {
|
if (buf.refCnt() <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,7 +217,7 @@ public final class NioDatagramChannel
|
|||||||
throw new ChannelException(cause);
|
throw new ChannelException(cause);
|
||||||
} finally {
|
} finally {
|
||||||
if (free) {
|
if (free) {
|
||||||
buffer.free();
|
buffer.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -258,7 +258,7 @@ public final class NioDatagramChannel
|
|||||||
buf.remove();
|
buf.remove();
|
||||||
|
|
||||||
// packet was written free up buffer
|
// packet was written free up buffer
|
||||||
packet.free();
|
packet.release();
|
||||||
|
|
||||||
if (buf.isEmpty()) {
|
if (buf.isEmpty()) {
|
||||||
// Wrote the outbound buffer completely - clear OP_WRITE.
|
// Wrote the outbound buffer completely - clear OP_WRITE.
|
||||||
|
@ -22,11 +22,11 @@ import io.netty.channel.ChannelException;
|
|||||||
import io.netty.channel.ChannelFuture;
|
import io.netty.channel.ChannelFuture;
|
||||||
import io.netty.channel.ChannelMetadata;
|
import io.netty.channel.ChannelMetadata;
|
||||||
import io.netty.channel.ChannelPromise;
|
import io.netty.channel.ChannelPromise;
|
||||||
|
import io.netty.channel.oio.AbstractOioMessageChannel;
|
||||||
import io.netty.channel.socket.DatagramChannel;
|
import io.netty.channel.socket.DatagramChannel;
|
||||||
import io.netty.channel.socket.DatagramChannelConfig;
|
import io.netty.channel.socket.DatagramChannelConfig;
|
||||||
import io.netty.channel.socket.DatagramPacket;
|
import io.netty.channel.socket.DatagramPacket;
|
||||||
import io.netty.channel.socket.DefaultDatagramChannelConfig;
|
import io.netty.channel.socket.DefaultDatagramChannelConfig;
|
||||||
import io.netty.channel.oio.AbstractOioMessageChannel;
|
|
||||||
import io.netty.logging.InternalLogger;
|
import io.netty.logging.InternalLogger;
|
||||||
import io.netty.logging.InternalLoggerFactory;
|
import io.netty.logging.InternalLoggerFactory;
|
||||||
|
|
||||||
@ -230,7 +230,7 @@ public class OioDatagramChannel extends AbstractOioMessageChannel
|
|||||||
throw new ChannelException(cause);
|
throw new ChannelException(cause);
|
||||||
} finally {
|
} finally {
|
||||||
if (free) {
|
if (free) {
|
||||||
buffer.free();
|
buffer.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -255,7 +255,7 @@ public class OioDatagramChannel extends AbstractOioMessageChannel
|
|||||||
}
|
}
|
||||||
socket.send(tmpPacket);
|
socket.send(tmpPacket);
|
||||||
} finally {
|
} finally {
|
||||||
p.free();
|
p.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ package io.netty.channel;
|
|||||||
|
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Freeable;
|
import io.netty.buffer.ReferenceCounted;
|
||||||
import io.netty.channel.ChannelHandler.Sharable;
|
import io.netty.channel.ChannelHandler.Sharable;
|
||||||
import io.netty.channel.local.LocalChannel;
|
import io.netty.channel.local.LocalChannel;
|
||||||
import io.netty.channel.local.LocalEventLoopGroup;
|
import io.netty.channel.local.LocalEventLoopGroup;
|
||||||
@ -121,15 +121,35 @@ public class DefaultChannelPipelineTest {
|
|||||||
public void testFreeCalled() throws InterruptedException{
|
public void testFreeCalled() throws InterruptedException{
|
||||||
final CountDownLatch free = new CountDownLatch(1);
|
final CountDownLatch free = new CountDownLatch(1);
|
||||||
|
|
||||||
final Freeable holder = new Freeable() {
|
final ReferenceCounted holder = new ReferenceCounted() {
|
||||||
@Override
|
@Override
|
||||||
public void free() {
|
public int refCnt() {
|
||||||
free.countDown();
|
return (int) free.getCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFreed() {
|
public void retain() {
|
||||||
return free.getCount() == 0;
|
fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void retain(int increment) {
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean release() {
|
||||||
|
assertEquals(1, refCnt());
|
||||||
|
free.countDown();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean release(int decrement) {
|
||||||
|
for (int i = 0; i < decrement; i ++) {
|
||||||
|
release();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
LocalChannel channel = new LocalChannel();
|
LocalChannel channel = new LocalChannel();
|
||||||
|
@ -424,7 +424,7 @@ public class LocalTransportThreadModelTest {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void freeOutboundBuffer(ChannelHandlerContext ctx) {
|
public void freeOutboundBuffer(ChannelHandlerContext ctx) {
|
||||||
ctx.outboundByteBuffer().free();
|
ctx.outboundByteBuffer().release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -523,7 +523,7 @@ public class LocalTransportThreadModelTest {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void freeInboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
public void freeInboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
||||||
ctx.inboundByteBuffer().free();
|
ctx.inboundByteBuffer().release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
Reference in New Issue
Block a user