1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.netty.buffer;
18
19 import io.netty.util.ResourceLeakDetector;
20 import io.netty.util.ResourceLeakTracker;
21 import io.netty.util.internal.ObjectUtil;
22
23 import java.nio.ByteOrder;
24
25 class SimpleLeakAwareByteBuf extends WrappedByteBuf {
26
27
28
29
30
31
32 private final ByteBuf trackedByteBuf;
33 final ResourceLeakTracker<ByteBuf> leak;
34
35 SimpleLeakAwareByteBuf(ByteBuf wrapped, ByteBuf trackedByteBuf, ResourceLeakTracker<ByteBuf> leak) {
36 super(wrapped);
37 this.trackedByteBuf = ObjectUtil.checkNotNull(trackedByteBuf, "trackedByteBuf");
38 this.leak = ObjectUtil.checkNotNull(leak, "leak");
39 }
40
41 SimpleLeakAwareByteBuf(ByteBuf wrapped, ResourceLeakTracker<ByteBuf> leak) {
42 this(wrapped, wrapped, leak);
43 }
44
45 @Override
46 public ByteBuf slice() {
47 return newSharedLeakAwareByteBuf(super.slice());
48 }
49
50 @Override
51 public ByteBuf retainedSlice() {
52 return unwrappedDerived(super.retainedSlice());
53 }
54
55 @Override
56 public ByteBuf retainedSlice(int index, int length) {
57 return unwrappedDerived(super.retainedSlice(index, length));
58 }
59
60 @Override
61 public ByteBuf retainedDuplicate() {
62 return unwrappedDerived(super.retainedDuplicate());
63 }
64
65 @Override
66 public ByteBuf readRetainedSlice(int length) {
67 return unwrappedDerived(super.readRetainedSlice(length));
68 }
69
70 @Override
71 public ByteBuf slice(int index, int length) {
72 return newSharedLeakAwareByteBuf(super.slice(index, length));
73 }
74
75 @Override
76 public ByteBuf duplicate() {
77 return newSharedLeakAwareByteBuf(super.duplicate());
78 }
79
80 @Override
81 public ByteBuf readSlice(int length) {
82 return newSharedLeakAwareByteBuf(super.readSlice(length));
83 }
84
85 @Override
86 public ByteBuf asReadOnly() {
87 return newSharedLeakAwareByteBuf(super.asReadOnly());
88 }
89
90 @Override
91 public ByteBuf touch() {
92 return this;
93 }
94
95 @Override
96 public ByteBuf touch(Object hint) {
97 return this;
98 }
99
100 @Override
101 public boolean release() {
102 if (super.release()) {
103 closeLeak();
104 return true;
105 }
106 return false;
107 }
108
109 @Override
110 public boolean release(int decrement) {
111 if (super.release(decrement)) {
112 closeLeak();
113 return true;
114 }
115 return false;
116 }
117
118 private void closeLeak() {
119
120
121 boolean closed = leak.close(trackedByteBuf);
122 assert closed;
123 }
124
125 @Override
126 public ByteBuf order(ByteOrder endianness) {
127 if (order() == endianness) {
128 return this;
129 } else {
130 return newSharedLeakAwareByteBuf(super.order(endianness));
131 }
132 }
133
134 private ByteBuf unwrappedDerived(ByteBuf derived) {
135
136
137 ByteBuf unwrappedDerived = unwrapSwapped(derived);
138
139 if (unwrappedDerived instanceof AbstractPooledDerivedByteBuf) {
140
141 ((AbstractPooledDerivedByteBuf) unwrappedDerived).parent(this);
142
143
144 return newLeakAwareByteBuf(derived, AbstractByteBuf.leakDetector.trackForcibly(derived));
145 }
146 return newSharedLeakAwareByteBuf(derived);
147 }
148
149 @SuppressWarnings("deprecation")
150 private static ByteBuf unwrapSwapped(ByteBuf buf) {
151 if (buf instanceof SwappedByteBuf) {
152 do {
153 buf = buf.unwrap();
154 } while (buf instanceof SwappedByteBuf);
155
156 return buf;
157 }
158 return buf;
159 }
160
161 private SimpleLeakAwareByteBuf newSharedLeakAwareByteBuf(
162 ByteBuf wrapped) {
163 return newLeakAwareByteBuf(wrapped, trackedByteBuf, leak);
164 }
165
166 private SimpleLeakAwareByteBuf newLeakAwareByteBuf(
167 ByteBuf wrapped, ResourceLeakTracker<ByteBuf> leakTracker) {
168 return newLeakAwareByteBuf(wrapped, wrapped, leakTracker);
169 }
170
171 protected SimpleLeakAwareByteBuf newLeakAwareByteBuf(
172 ByteBuf buf, ByteBuf trackedByteBuf, ResourceLeakTracker<ByteBuf> leakTracker) {
173 return new SimpleLeakAwareByteBuf(buf, trackedByteBuf, leakTracker);
174 }
175 }