Enable a user specify an arbitrary information with ReferenceCounted.touch()
- Related: #2163 - Add ResourceLeakHint to allow a user to provide a meaningful information about the leak when touching it - DefaultChannelHandlerContext now implements ResourceLeakHint to tell where the message is going. - Cleaner resource leak report by excluding noisy stack trace elements
This commit is contained in:
parent
0235244e55
commit
8837afddf8
@ -51,6 +51,12 @@ public abstract class AbstractDerivedByteBuf extends AbstractByteBuf {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ByteBuf touch(Object hint) {
|
||||
unwrap().touch(hint);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean release() {
|
||||
return unwrap().release();
|
||||
|
@ -95,7 +95,12 @@ public abstract class AbstractReferenceCountedByteBuf extends AbstractByteBuf {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ByteBuf touch() {
|
||||
public ByteBuf touch() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf touch(Object hint) {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -706,6 +706,12 @@ final class AdvancedLeakAwareByteBuf extends WrappedByteBuf {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf touch(Object hint) {
|
||||
leak.record(hint);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean release() {
|
||||
boolean deallocated = super.release();
|
||||
|
@ -1880,4 +1880,7 @@ public abstract class ByteBuf implements ReferenceCounted, Comparable<ByteBuf> {
|
||||
|
||||
@Override
|
||||
public abstract ByteBuf touch();
|
||||
|
||||
@Override
|
||||
public abstract ByteBuf touch(Object hint);
|
||||
}
|
||||
|
@ -45,4 +45,7 @@ public interface ByteBufHolder extends ReferenceCounted {
|
||||
|
||||
@Override
|
||||
ByteBufHolder touch();
|
||||
|
||||
@Override
|
||||
ByteBufHolder touch(Object hint);
|
||||
}
|
||||
|
@ -1570,6 +1570,16 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf {
|
||||
return (CompositeByteBuf) super.retain();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompositeByteBuf touch() {
|
||||
return (CompositeByteBuf) super.touch();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompositeByteBuf touch(Object hint) {
|
||||
return (CompositeByteBuf) super.touch(hint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer[] nioBuffers() {
|
||||
return nioBuffers(readerIndex(), readableBytes());
|
||||
|
@ -74,6 +74,12 @@ public class DefaultByteBufHolder implements ByteBufHolder {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBufHolder touch(Object hint) {
|
||||
data.touch(hint);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean release() {
|
||||
return data.release();
|
||||
|
@ -836,6 +836,11 @@ public final class EmptyByteBuf extends ByteBuf {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf touch(Object hint) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean release() {
|
||||
return false;
|
||||
|
@ -34,6 +34,11 @@ final class SimpleLeakAwareByteBuf extends WrappedByteBuf {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf touch(Object hint) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean release() {
|
||||
boolean deallocated = super.release();
|
||||
|
@ -820,6 +820,12 @@ public final class SwappedByteBuf extends ByteBuf {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf touch(Object hint) {
|
||||
buf.touch(hint);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean release() {
|
||||
return buf.release();
|
||||
|
@ -80,6 +80,11 @@ final class UnreleasableByteBuf extends WrappedByteBuf {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf touch(Object hint) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean release() {
|
||||
return false;
|
||||
|
@ -805,6 +805,12 @@ class WrappedByteBuf extends ByteBuf {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf touch(Object hint) {
|
||||
buf.touch(hint);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadable(int size) {
|
||||
return buf.isReadable(size);
|
||||
|
@ -54,6 +54,11 @@ final class ComposedLastHttpContent implements LastHttpContent {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LastHttpContent touch(Object hint) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LastHttpContent duplicate() {
|
||||
return copy();
|
||||
|
@ -78,6 +78,12 @@ public class DefaultFullHttpRequest extends DefaultHttpRequest implements FullHt
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FullHttpRequest touch(Object hint) {
|
||||
content.touch(hint);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean release() {
|
||||
return content.release();
|
||||
|
@ -80,6 +80,12 @@ public class DefaultFullHttpResponse extends DefaultHttpResponse implements Full
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FullHttpResponse touch(Object hint) {
|
||||
content.touch(hint);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean release() {
|
||||
return content.release();
|
||||
|
@ -73,6 +73,12 @@ public class DefaultHttpContent extends DefaultHttpObject implements HttpContent
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpContent touch(Object hint) {
|
||||
content.touch(hint);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean release() {
|
||||
return content.release();
|
||||
|
@ -75,6 +75,12 @@ public class DefaultLastHttpContent extends DefaultHttpContent implements LastHt
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LastHttpContent touch(Object hint) {
|
||||
super.touch(hint);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders trailingHeaders() {
|
||||
return trailingHeaders;
|
||||
|
@ -32,6 +32,9 @@ public interface FullHttpMessage extends HttpMessage, LastHttpContent {
|
||||
@Override
|
||||
FullHttpMessage touch();
|
||||
|
||||
@Override
|
||||
FullHttpMessage touch(Object hint);
|
||||
|
||||
@Override
|
||||
FullHttpMessage duplicate();
|
||||
}
|
||||
|
@ -32,6 +32,9 @@ public interface FullHttpRequest extends HttpRequest, FullHttpMessage {
|
||||
@Override
|
||||
FullHttpRequest touch();
|
||||
|
||||
@Override
|
||||
FullHttpRequest touch(Object hint);
|
||||
|
||||
@Override
|
||||
FullHttpRequest duplicate();
|
||||
|
||||
|
@ -32,6 +32,9 @@ public interface FullHttpResponse extends HttpResponse, FullHttpMessage {
|
||||
@Override
|
||||
FullHttpResponse touch();
|
||||
|
||||
@Override
|
||||
FullHttpResponse touch(Object hint);
|
||||
|
||||
@Override
|
||||
FullHttpResponse duplicate();
|
||||
|
||||
|
@ -41,4 +41,7 @@ public interface HttpContent extends HttpObject, ByteBufHolder {
|
||||
|
||||
@Override
|
||||
HttpContent touch();
|
||||
|
||||
@Override
|
||||
HttpContent touch(Object hint);
|
||||
}
|
||||
|
@ -79,6 +79,11 @@ public interface LastHttpContent extends HttpContent {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LastHttpContent touch(Object hint) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean release() {
|
||||
return false;
|
||||
@ -109,6 +114,9 @@ public interface LastHttpContent extends HttpContent {
|
||||
@Override
|
||||
LastHttpContent touch();
|
||||
|
||||
@Override
|
||||
LastHttpContent touch(Object hint);
|
||||
|
||||
@Override
|
||||
LastHttpContent duplicate();
|
||||
}
|
||||
|
@ -401,4 +401,9 @@ public abstract class AbstractDiskHttpData extends AbstractHttpData {
|
||||
public HttpData touch() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpData touch(Object hint) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -133,4 +133,7 @@ public abstract class AbstractHttpData extends AbstractReferenceCounted implemen
|
||||
|
||||
@Override
|
||||
public abstract HttpData touch();
|
||||
|
||||
@Override
|
||||
public abstract HttpData touch(Object hint);
|
||||
}
|
||||
|
@ -260,8 +260,13 @@ public abstract class AbstractMemoryHttpData extends AbstractHttpData {
|
||||
|
||||
@Override
|
||||
public HttpData touch() {
|
||||
return touch(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpData touch(Object hint) {
|
||||
if (byteBuf != null) {
|
||||
byteBuf.touch();
|
||||
byteBuf.touch(hint);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
@ -45,4 +45,7 @@ public interface Attribute extends HttpData {
|
||||
|
||||
@Override
|
||||
Attribute touch();
|
||||
|
||||
@Override
|
||||
Attribute touch(Object hint);
|
||||
}
|
||||
|
@ -198,4 +198,10 @@ public class DiskAttribute extends AbstractDiskHttpData implements Attribute {
|
||||
super.touch();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Attribute touch(Object hint) {
|
||||
super.touch(hint);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -217,4 +217,10 @@ public class DiskFileUpload extends AbstractDiskHttpData implements FileUpload {
|
||||
super.touch();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileUpload touch(Object hint) {
|
||||
super.touch(hint);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -70,4 +70,7 @@ public interface FileUpload extends HttpData {
|
||||
|
||||
@Override
|
||||
FileUpload touch();
|
||||
|
||||
@Override
|
||||
FileUpload touch(Object hint);
|
||||
}
|
||||
|
@ -211,4 +211,7 @@ public interface HttpData extends InterfaceHttpData, ByteBufHolder {
|
||||
|
||||
@Override
|
||||
HttpData touch();
|
||||
|
||||
@Override
|
||||
HttpData touch(Object hint);
|
||||
}
|
||||
|
@ -1221,6 +1221,12 @@ public class HttpPostRequestEncoder implements ChunkedInput<HttpContent> {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FullHttpRequest touch(Object hint) {
|
||||
content.touch(hint);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf content() {
|
||||
return content.content();
|
||||
|
@ -44,4 +44,7 @@ public interface InterfaceHttpData extends Comparable<InterfaceHttpData>, Refere
|
||||
|
||||
@Override
|
||||
InterfaceHttpData touch();
|
||||
|
||||
@Override
|
||||
InterfaceHttpData touch(Object hint);
|
||||
}
|
||||
|
@ -149,4 +149,12 @@ final class InternalAttribute extends AbstractReferenceCounted implements Interf
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InterfaceHttpData touch(Object hint) {
|
||||
for (ByteBuf buf: value) {
|
||||
buf.touch(hint);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -159,4 +159,10 @@ public class MemoryAttribute extends AbstractMemoryHttpData implements Attribute
|
||||
super.touch();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Attribute touch(Object hint) {
|
||||
super.touch(hint);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -177,4 +177,10 @@ public class MemoryFileUpload extends AbstractMemoryHttpData implements FileUplo
|
||||
super.touch();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileUpload touch(Object hint) {
|
||||
super.touch(hint);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -285,6 +285,12 @@ public class MixedAttribute implements Attribute {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Attribute touch(Object hint) {
|
||||
attribute.touch(hint);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean release() {
|
||||
return attribute.release();
|
||||
|
@ -316,6 +316,12 @@ public class MixedFileUpload implements FileUpload {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileUpload touch(Object hint) {
|
||||
fileUpload.touch(hint);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean release() {
|
||||
return fileUpload.release();
|
||||
|
@ -81,4 +81,10 @@ public class BinaryWebSocketFrame extends WebSocketFrame {
|
||||
super.touch();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryWebSocketFrame touch(Object hint) {
|
||||
super.touch(hint);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -165,4 +165,10 @@ public class CloseWebSocketFrame extends WebSocketFrame {
|
||||
super.touch();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CloseWebSocketFrame touch(Object hint) {
|
||||
super.touch(hint);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -146,4 +146,10 @@ public class ContinuationWebSocketFrame extends WebSocketFrame {
|
||||
super.touch();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContinuationWebSocketFrame touch(Object hint) {
|
||||
super.touch(hint);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -81,4 +81,10 @@ public class PingWebSocketFrame extends WebSocketFrame {
|
||||
super.touch();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PingWebSocketFrame touch(Object hint) {
|
||||
super.touch(hint);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -81,4 +81,10 @@ public class PongWebSocketFrame extends WebSocketFrame {
|
||||
super.touch();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PongWebSocketFrame touch(Object hint) {
|
||||
super.touch(hint);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -121,4 +121,10 @@ public class TextWebSocketFrame extends WebSocketFrame {
|
||||
super.touch();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextWebSocketFrame touch(Object hint) {
|
||||
super.touch(hint);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -88,4 +88,10 @@ public abstract class WebSocketFrame extends DefaultByteBufHolder {
|
||||
super.touch();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebSocketFrame touch(Object hint) {
|
||||
super.touch(hint);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -115,6 +115,12 @@ public class DefaultSpdyDataFrame extends DefaultSpdyStreamFrame implements Spdy
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpdyDataFrame touch(Object hint) {
|
||||
data.touch(hint);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean release() {
|
||||
return data.release();
|
||||
|
@ -53,4 +53,7 @@ public interface SpdyDataFrame extends ByteBufHolder, SpdyStreamFrame {
|
||||
|
||||
@Override
|
||||
SpdyDataFrame touch();
|
||||
|
||||
@Override
|
||||
SpdyDataFrame touch(Object hint);
|
||||
}
|
||||
|
@ -50,6 +50,12 @@ public class DefaultLastMemcacheContent extends DefaultMemcacheContent implement
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LastMemcacheContent touch(Object hint) {
|
||||
super.touch(hint);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LastMemcacheContent copy() {
|
||||
return new DefaultLastMemcacheContent(content().copy());
|
||||
|
@ -73,6 +73,12 @@ public class DefaultMemcacheContent extends AbstractMemcacheObject implements Me
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MemcacheContent touch(Object hint) {
|
||||
content.touch(hint);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean release() {
|
||||
return content.release();
|
||||
|
@ -33,6 +33,9 @@ public interface FullMemcacheMessage extends MemcacheMessage, LastMemcacheConten
|
||||
@Override
|
||||
FullMemcacheMessage touch();
|
||||
|
||||
@Override
|
||||
FullMemcacheMessage touch(Object hint);
|
||||
|
||||
@Override
|
||||
FullMemcacheMessage duplicate();
|
||||
}
|
||||
|
@ -50,6 +50,11 @@ public interface LastMemcacheContent extends MemcacheContent {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LastMemcacheContent touch(Object hint) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LastMemcacheContent duplicate() {
|
||||
return this;
|
||||
@ -98,6 +103,9 @@ public interface LastMemcacheContent extends MemcacheContent {
|
||||
@Override
|
||||
LastMemcacheContent touch();
|
||||
|
||||
@Override
|
||||
LastMemcacheContent touch(Object hint);
|
||||
|
||||
@Override
|
||||
LastMemcacheContent duplicate();
|
||||
}
|
||||
|
@ -42,4 +42,7 @@ public interface MemcacheContent extends MemcacheObject, ByteBufHolder {
|
||||
|
||||
@Override
|
||||
MemcacheContent touch();
|
||||
|
||||
@Override
|
||||
MemcacheContent touch(Object hint);
|
||||
}
|
||||
|
@ -36,4 +36,7 @@ public interface MemcacheMessage extends MemcacheObject, ReferenceCounted {
|
||||
|
||||
@Override
|
||||
MemcacheMessage touch();
|
||||
|
||||
@Override
|
||||
MemcacheMessage touch(Object hint);
|
||||
}
|
||||
|
@ -110,8 +110,13 @@ public abstract class AbstractBinaryMemcacheMessage<H extends BinaryMemcacheMess
|
||||
|
||||
@Override
|
||||
public BinaryMemcacheMessage<H> touch() {
|
||||
return touch(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryMemcacheMessage<H> touch(Object hint) {
|
||||
if (extras != null) {
|
||||
extras.touch();
|
||||
extras.touch(hint);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
@ -66,4 +66,7 @@ public interface BinaryMemcacheMessage<H extends BinaryMemcacheMessageHeader> ex
|
||||
|
||||
@Override
|
||||
BinaryMemcacheMessage<H> touch();
|
||||
|
||||
@Override
|
||||
BinaryMemcacheMessage<H> touch(Object hint);
|
||||
}
|
||||
|
@ -36,4 +36,7 @@ public interface BinaryMemcacheRequest extends BinaryMemcacheMessage<BinaryMemca
|
||||
|
||||
@Override
|
||||
BinaryMemcacheRequest touch();
|
||||
|
||||
@Override
|
||||
BinaryMemcacheRequest touch(Object hint);
|
||||
}
|
||||
|
@ -36,4 +36,7 @@ public interface BinaryMemcacheResponse extends BinaryMemcacheMessage<BinaryMemc
|
||||
|
||||
@Override
|
||||
BinaryMemcacheResponse touch();
|
||||
|
||||
@Override
|
||||
BinaryMemcacheResponse touch(Object hint);
|
||||
}
|
||||
|
@ -80,4 +80,10 @@ public class DefaultBinaryMemcacheRequest extends AbstractBinaryMemcacheMessage<
|
||||
super.touch();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryMemcacheRequest touch(Object hint) {
|
||||
super.touch(hint);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -80,4 +80,10 @@ public class DefaultBinaryMemcacheResponse extends AbstractBinaryMemcacheMessage
|
||||
super.touch();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryMemcacheResponse touch(Object hint) {
|
||||
super.touch(hint);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -83,6 +83,12 @@ public class DefaultFullBinaryMemcacheRequest extends DefaultBinaryMemcacheReque
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FullBinaryMemcacheRequest touch(Object hint) {
|
||||
content.touch(hint);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean release() {
|
||||
return content.release();
|
||||
|
@ -83,6 +83,12 @@ public class DefaultFullBinaryMemcacheResponse extends DefaultBinaryMemcacheResp
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FullBinaryMemcacheResponse touch(Object hint) {
|
||||
content.touch(hint);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean release() {
|
||||
return content.release();
|
||||
|
@ -34,6 +34,9 @@ public interface FullBinaryMemcacheRequest extends BinaryMemcacheRequest, FullMe
|
||||
@Override
|
||||
FullBinaryMemcacheRequest touch();
|
||||
|
||||
@Override
|
||||
FullBinaryMemcacheRequest touch(Object hint);
|
||||
|
||||
@Override
|
||||
FullBinaryMemcacheRequest duplicate();
|
||||
}
|
||||
|
@ -34,6 +34,9 @@ public interface FullBinaryMemcacheResponse extends BinaryMemcacheResponse, Full
|
||||
@Override
|
||||
FullBinaryMemcacheResponse touch();
|
||||
|
||||
@Override
|
||||
FullBinaryMemcacheResponse touch(Object hint);
|
||||
|
||||
@Override
|
||||
FullBinaryMemcacheResponse duplicate();
|
||||
}
|
||||
|
@ -978,6 +978,12 @@ final class ReplayingDecoderBuffer extends ByteBuf {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf touch(Object hint) {
|
||||
buffer.touch(hint);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean release() {
|
||||
reject();
|
||||
|
@ -88,6 +88,11 @@ public abstract class AbstractReferenceCounted implements ReferenceCounted {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReferenceCounted touch() {
|
||||
return touch(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean release() {
|
||||
for (;;) {
|
||||
|
@ -71,6 +71,19 @@ public final class ReferenceCountUtil {
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to call {@link ReferenceCounted#touch(Object)} if the specified message implements
|
||||
* {@link ReferenceCounted}. If the specified message doesn't implement {@link ReferenceCounted},
|
||||
* this method does nothing.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T touch(T msg, Object hint) {
|
||||
if (msg instanceof ReferenceCounted) {
|
||||
return (T) ((ReferenceCounted) msg).touch(hint);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
@ -48,10 +48,17 @@ public interface ReferenceCounted {
|
||||
/**
|
||||
* Records the current access location of this object for debugging purposes.
|
||||
* If this object is determined to be leaked, the information recorded by this operation will be provided to you
|
||||
* via {@link ResourceLeakDetector}.
|
||||
* via {@link ResourceLeakDetector}. This method is a shortcut to {@link #touch(Object) touch(null)}.
|
||||
*/
|
||||
ReferenceCounted touch();
|
||||
|
||||
/**
|
||||
* Records the current access location of this object with an additonal arbitrary information for debugging
|
||||
* purposes. If this object is determined to be leaked, the information recorded by this operation will be
|
||||
* provided to you via {@link ResourceLeakDetector}.
|
||||
*/
|
||||
ReferenceCounted touch(Object hint);
|
||||
|
||||
/**
|
||||
* Decreases the reference count by {@code 1} and deallocates this object if the reference count reaches at
|
||||
* {@code 0}.
|
||||
|
@ -19,10 +19,16 @@ package io.netty.util;
|
||||
public interface ResourceLeak {
|
||||
/**
|
||||
* Records the caller's current stack trace so that the {@link ResourceLeakDetector} can tell where the leaked
|
||||
* resource was accessed lastly.
|
||||
* resource was accessed lastly. This method is a shortcut to {@link #record(Object) record(null)}.
|
||||
*/
|
||||
void record();
|
||||
|
||||
/**
|
||||
* Records the caller's current stack trace and the specified additional arbitrary information
|
||||
* so that the {@link ResourceLeakDetector} can tell where the leaked resource was accessed lastly.
|
||||
*/
|
||||
void record(Object hint);
|
||||
|
||||
/**
|
||||
* Close the leak so that {@link ResourceLeakDetector} does not warn about leaked resources.
|
||||
*
|
||||
|
@ -265,7 +265,7 @@ public final class ResourceLeakDetector<T> {
|
||||
if (referent != null) {
|
||||
Level level = getLevel();
|
||||
if (level.ordinal() >= Level.ADVANCED.ordinal()) {
|
||||
creationRecord = newRecord(3);
|
||||
creationRecord = newRecord(null, 3);
|
||||
} else {
|
||||
creationRecord = null;
|
||||
}
|
||||
@ -287,8 +287,17 @@ public final class ResourceLeakDetector<T> {
|
||||
|
||||
@Override
|
||||
public void record() {
|
||||
record0(null, 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void record(Object hint) {
|
||||
record0(hint, 3);
|
||||
}
|
||||
|
||||
private void record0(Object hint, int recordsToSkip) {
|
||||
if (creationRecord != null) {
|
||||
String value = newRecord(2);
|
||||
String value = newRecord(hint, recordsToSkip);
|
||||
|
||||
synchronized (lastRecords) {
|
||||
int size = lastRecords.size();
|
||||
@ -353,11 +362,27 @@ public final class ResourceLeakDetector<T> {
|
||||
}
|
||||
|
||||
private static final String[] STACK_TRACE_ELEMENT_EXCLUSIONS = {
|
||||
"io.netty.util.ReferenceCountUtil.touch(",
|
||||
"io.netty.buffer.AdvancedLeakAwareByteBuf.touch(",
|
||||
"io.netty.buffer.AbstractByteBufAllocator.toLeakAwareBuffer(",
|
||||
};
|
||||
|
||||
static String newRecord(int recordsToSkip) {
|
||||
static String newRecord(Object hint, int recordsToSkip) {
|
||||
StringBuilder buf = new StringBuilder(4096);
|
||||
|
||||
// Append the hint first if available.
|
||||
if (hint != null) {
|
||||
buf.append("\tHint: ");
|
||||
// Prefer a hint string to a simple string form.
|
||||
if (hint instanceof ResourceLeakHint) {
|
||||
buf.append(((ResourceLeakHint) hint).toHintString());
|
||||
} else {
|
||||
buf.append(hint);
|
||||
}
|
||||
buf.append(NEWLINE);
|
||||
}
|
||||
|
||||
// Append the stack trace.
|
||||
StackTraceElement[] array = new Throwable().getStackTrace();
|
||||
for (StackTraceElement e: array) {
|
||||
if (recordsToSkip > 0) {
|
||||
|
27
common/src/main/java/io/netty/util/ResourceLeakHint.java
Normal file
27
common/src/main/java/io/netty/util/ResourceLeakHint.java
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2014 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.util;
|
||||
|
||||
/**
|
||||
* A hint object that provides human-readable message for easier resource leak tracking.
|
||||
*/
|
||||
public interface ResourceLeakHint {
|
||||
/**
|
||||
* Returns a human-readable message that potentially enables easier resource leak tracking.
|
||||
*/
|
||||
String toHintString();
|
||||
}
|
@ -158,6 +158,12 @@ public final class SctpMessage extends DefaultByteBufHolder {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SctpMessage touch(Object hint) {
|
||||
super.touch(hint);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (refCnt() == 0) {
|
||||
|
@ -58,4 +58,10 @@ public final class UdtMessage extends DefaultByteBufHolder {
|
||||
super.touch();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UdtMessage touch(Object hint) {
|
||||
super.touch(hint);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -41,4 +41,16 @@ public interface AddressedEnvelope<M, A extends SocketAddress> extends Reference
|
||||
* Returns the address of the recipient of this message.
|
||||
*/
|
||||
A recipient();
|
||||
|
||||
@Override
|
||||
AddressedEnvelope<M, A> retain();
|
||||
|
||||
@Override
|
||||
AddressedEnvelope<M, A> retain(int increment);
|
||||
|
||||
@Override
|
||||
AddressedEnvelope<M, A> touch();
|
||||
|
||||
@Override
|
||||
AddressedEnvelope<M, A> touch(Object hint);
|
||||
}
|
||||
|
@ -108,6 +108,12 @@ public class DefaultAddressedEnvelope<M, A extends SocketAddress> implements Add
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AddressedEnvelope<M, A> touch(Object hint) {
|
||||
ReferenceCountUtil.touch(message, hint);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (sender != null) {
|
||||
|
@ -20,6 +20,7 @@ import io.netty.util.Attribute;
|
||||
import io.netty.util.AttributeKey;
|
||||
import io.netty.util.Recycler;
|
||||
import io.netty.util.ReferenceCountUtil;
|
||||
import io.netty.util.ResourceLeakHint;
|
||||
import io.netty.util.concurrent.EventExecutor;
|
||||
import io.netty.util.concurrent.EventExecutorGroup;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
@ -28,7 +29,7 @@ import java.net.SocketAddress;
|
||||
|
||||
import static io.netty.channel.DefaultChannelPipeline.*;
|
||||
|
||||
final class DefaultChannelHandlerContext implements ChannelHandlerContext {
|
||||
final class DefaultChannelHandlerContext implements ChannelHandlerContext, ResourceLeakHint {
|
||||
|
||||
volatile DefaultChannelHandlerContext next;
|
||||
volatile DefaultChannelHandlerContext prev;
|
||||
@ -329,8 +330,8 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext {
|
||||
throw new NullPointerException("msg");
|
||||
}
|
||||
|
||||
ReferenceCountUtil.touch(msg);
|
||||
final DefaultChannelHandlerContext next = findContextInbound();
|
||||
ReferenceCountUtil.touch(msg, next);
|
||||
EventExecutor executor = next.executor();
|
||||
if (executor.inEventLoop()) {
|
||||
next.invokeChannelRead(msg);
|
||||
@ -706,8 +707,8 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext {
|
||||
|
||||
private void write(Object msg, boolean flush, ChannelPromise promise) {
|
||||
|
||||
ReferenceCountUtil.touch(msg);
|
||||
DefaultChannelHandlerContext next = findContextOutbound();
|
||||
ReferenceCountUtil.touch(msg, next);
|
||||
EventExecutor executor = next.executor();
|
||||
if (executor.inEventLoop()) {
|
||||
next.invokeWrite(msg, promise);
|
||||
@ -987,4 +988,14 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext {
|
||||
RECYCLER.recycle(this, handle);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toHintString() {
|
||||
return '\'' + name + "' will handle the message from this point.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return StringUtil.simpleClassName(ChannelHandlerContext.class) + '(' + name + ", " + channel + ')';
|
||||
}
|
||||
}
|
||||
|
@ -121,4 +121,9 @@ public class DefaultFileRegion extends AbstractReferenceCounted implements FileR
|
||||
public FileRegion touch() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileRegion touch(Object hint) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -89,4 +89,7 @@ public interface FileRegion extends ReferenceCounted {
|
||||
|
||||
@Override
|
||||
FileRegion touch();
|
||||
|
||||
@Override
|
||||
FileRegion touch(Object hint);
|
||||
}
|
||||
|
@ -69,4 +69,10 @@ public final class DatagramPacket
|
||||
super.touch();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DatagramPacket touch(Object hint) {
|
||||
super.touch(hint);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ public class DefaultChannelPipelineTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReferenceCounted touch() {
|
||||
public ReferenceCounted touch(Object hint) {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user