Fix a race condition in reference counter implementation / Reference count never goes below 0
This commit is contained in:
parent
bd0729ac45
commit
4f6d05365a
@ -1032,7 +1032,7 @@ public abstract class AbstractByteBuf implements ByteBuf {
|
||||
}
|
||||
|
||||
protected final void ensureAccessible() {
|
||||
if (refCnt() <= 0) {
|
||||
if (refCnt() == 0) {
|
||||
throw new IllegalBufferAccessException();
|
||||
}
|
||||
}
|
||||
|
@ -32,15 +32,18 @@ public abstract class AbstractReferenceCounted implements ReferenceCounted {
|
||||
|
||||
@Override
|
||||
public final void retain() {
|
||||
do {
|
||||
for (;;) {
|
||||
int refCnt = this.refCnt;
|
||||
if (refCnt <= 0) {
|
||||
if (refCnt == 0) {
|
||||
throw new IllegalBufferAccessException();
|
||||
}
|
||||
if (refCnt == Integer.MAX_VALUE) {
|
||||
throw new IllegalBufferAccessException("refCnt overflow");
|
||||
}
|
||||
} while (!refCntUpdater.compareAndSet(this, refCnt, refCnt + 1));
|
||||
if (refCntUpdater.compareAndSet(this, refCnt, refCnt + 1)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -49,22 +52,25 @@ public abstract class AbstractReferenceCounted implements ReferenceCounted {
|
||||
throw new IllegalArgumentException("increment: " + increment + " (expected: > 0)");
|
||||
}
|
||||
|
||||
do {
|
||||
for (;;) {
|
||||
int refCnt = this.refCnt;
|
||||
if (refCnt <= 0) {
|
||||
if (refCnt == 0) {
|
||||
throw new IllegalBufferAccessException();
|
||||
}
|
||||
if (refCnt > Integer.MAX_VALUE - increment) {
|
||||
throw new IllegalBufferAccessException("refCnt overflow");
|
||||
}
|
||||
} while (!refCntUpdater.compareAndSet(this, refCnt, refCnt + increment));
|
||||
if (refCntUpdater.compareAndSet(this, refCnt, refCnt + increment)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean release() {
|
||||
for (;;) {
|
||||
int refCnt = this.refCnt;
|
||||
if (refCnt <= 0) {
|
||||
if (refCnt == 0) {
|
||||
throw new IllegalBufferAccessException();
|
||||
}
|
||||
|
||||
|
@ -37,15 +37,18 @@ public abstract class AbstractReferenceCountedByteBuf extends AbstractByteBuf {
|
||||
|
||||
@Override
|
||||
public final void retain() {
|
||||
do {
|
||||
for (;;) {
|
||||
int refCnt = this.refCnt;
|
||||
if (refCnt <= 0) {
|
||||
if (refCnt == 0) {
|
||||
throw new IllegalBufferAccessException();
|
||||
}
|
||||
if (refCnt == Integer.MAX_VALUE) {
|
||||
throw new IllegalBufferAccessException("refCnt overflow");
|
||||
}
|
||||
} while (!refCntUpdater.compareAndSet(this, refCnt, refCnt + 1));
|
||||
if (refCntUpdater.compareAndSet(this, refCnt, refCnt + 1)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -54,22 +57,25 @@ public abstract class AbstractReferenceCountedByteBuf extends AbstractByteBuf {
|
||||
throw new IllegalArgumentException("increment: " + increment + " (expected: > 0)");
|
||||
}
|
||||
|
||||
do {
|
||||
for (;;) {
|
||||
int refCnt = this.refCnt;
|
||||
if (refCnt <= 0) {
|
||||
if (refCnt == 0) {
|
||||
throw new IllegalBufferAccessException();
|
||||
}
|
||||
if (refCnt > Integer.MAX_VALUE - increment) {
|
||||
throw new IllegalBufferAccessException("refCnt overflow");
|
||||
}
|
||||
} while (!refCntUpdater.compareAndSet(this, refCnt, refCnt + increment));
|
||||
if (refCntUpdater.compareAndSet(this, refCnt, refCnt + increment)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean release() {
|
||||
for (;;) {
|
||||
int refCnt = this.refCnt;
|
||||
if (refCnt <= 0) {
|
||||
if (refCnt == 0) {
|
||||
throw new IllegalBufferAccessException();
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,7 @@ public class DefaultSpdyDataFrame extends DefaultByteBufHolder implements SpdyDa
|
||||
buf.append(streamId);
|
||||
buf.append(StringUtil.NEWLINE);
|
||||
buf.append("--> Size = ");
|
||||
if (refCnt() <= 0) {
|
||||
if (refCnt() == 0) {
|
||||
buf.append("(freed)");
|
||||
} else {
|
||||
buf.append(data().readableBytes());
|
||||
|
@ -137,7 +137,7 @@ public final class SctpMessage extends DefaultByteBufHolder {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (refCnt() <= 0) {
|
||||
if (refCnt() == 0) {
|
||||
return "SctpFrame{" +
|
||||
"streamIdentifier=" + streamIdentifier + ", protocolIdentifier=" + protocolIdentifier +
|
||||
", data=(FREED)}";
|
||||
|
@ -57,7 +57,7 @@ public final class DatagramPacket extends DefaultByteBufHolder {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (refCnt() <= 0) {
|
||||
if (refCnt() == 0) {
|
||||
return "DatagramPacket{remoteAddress=" + remoteAddress().toString() +
|
||||
", data=(FREED)}";
|
||||
}
|
||||
|
@ -254,7 +254,7 @@ public class AioSocketChannel extends AbstractAioChannel implements SocketChanne
|
||||
try {
|
||||
if (buf.isReadable()) {
|
||||
for (;;) {
|
||||
if (buf.refCnt() <= 0) {
|
||||
if (buf.refCnt() == 0) {
|
||||
break;
|
||||
}
|
||||
// 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;
|
||||
|
||||
ByteBuf buf = channel.unsafe().directOutboundContext().outboundByteBuffer();
|
||||
if (buf.refCnt() <= 0) {
|
||||
if (buf.refCnt() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user