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.IllegalReferenceCountException;
20 import io.netty.util.Recycler.EnhancedHandle;
21 import io.netty.util.internal.ObjectPool.Handle;
22
23 import java.nio.ByteBuffer;
24 import java.nio.ByteOrder;
25
26
27
28
29 abstract class AbstractPooledDerivedByteBuf extends AbstractReferenceCountedByteBuf {
30
31 private final EnhancedHandle<AbstractPooledDerivedByteBuf> recyclerHandle;
32 private AbstractByteBuf rootParent;
33
34
35
36
37
38
39 private ByteBuf parent;
40
41 @SuppressWarnings("unchecked")
42 AbstractPooledDerivedByteBuf(Handle<? extends AbstractPooledDerivedByteBuf> recyclerHandle) {
43 super(0);
44 this.recyclerHandle = (EnhancedHandle<AbstractPooledDerivedByteBuf>) recyclerHandle;
45 }
46
47
48 final void parent(ByteBuf newParent) {
49 assert newParent instanceof SimpleLeakAwareByteBuf;
50 parent = newParent;
51 }
52
53 @Override
54 public final AbstractByteBuf unwrap() {
55 AbstractByteBuf rootParent = this.rootParent;
56 if (rootParent == null) {
57 throw new IllegalReferenceCountException();
58 }
59 return rootParent;
60 }
61
62 final <U extends AbstractPooledDerivedByteBuf> U init(
63 AbstractByteBuf unwrapped, ByteBuf wrapped, int readerIndex, int writerIndex, int maxCapacity) {
64 wrapped.retain();
65 parent = wrapped;
66 rootParent = unwrapped;
67
68 try {
69 maxCapacity(maxCapacity);
70 setIndex0(readerIndex, writerIndex);
71 resetRefCnt();
72
73 @SuppressWarnings("unchecked")
74 final U castThis = (U) this;
75 wrapped = null;
76 return castThis;
77 } finally {
78 if (wrapped != null) {
79 parent = rootParent = null;
80 wrapped.release();
81 }
82 }
83 }
84
85 @Override
86 protected final void deallocate() {
87
88
89
90 ByteBuf parent = this.parent;
91
92 this.parent = this.rootParent = null;
93 recyclerHandle.unguardedRecycle(this);
94 parent.release();
95 }
96
97 @Override
98 public final ByteBufAllocator alloc() {
99 return unwrap().alloc();
100 }
101
102 @Override
103 @Deprecated
104 public final ByteOrder order() {
105 return unwrap().order();
106 }
107
108 @Override
109 public boolean isReadOnly() {
110 return unwrap().isReadOnly();
111 }
112
113 @Override
114 public final boolean isDirect() {
115 return unwrap().isDirect();
116 }
117
118 @Override
119 public boolean hasArray() {
120 return unwrap().hasArray();
121 }
122
123 @Override
124 public byte[] array() {
125 return unwrap().array();
126 }
127
128 @Override
129 public boolean hasMemoryAddress() {
130 return unwrap().hasMemoryAddress();
131 }
132
133 @Override
134 public boolean isContiguous() {
135 return unwrap().isContiguous();
136 }
137
138 @Override
139 public final int nioBufferCount() {
140 return unwrap().nioBufferCount();
141 }
142
143 @Override
144 public final ByteBuffer internalNioBuffer(int index, int length) {
145 return nioBuffer(index, length);
146 }
147
148 @Override
149 public final ByteBuf retainedSlice() {
150 final int index = readerIndex();
151 return retainedSlice(index, writerIndex() - index);
152 }
153
154 @Override
155 public ByteBuf slice(int index, int length) {
156 ensureAccessible();
157
158 return new PooledNonRetainedSlicedByteBuf(this, unwrap(), index, length);
159 }
160
161 final ByteBuf duplicate0() {
162 ensureAccessible();
163
164 return new PooledNonRetainedDuplicateByteBuf(this, unwrap());
165 }
166
167 private static final class PooledNonRetainedDuplicateByteBuf extends UnpooledDuplicatedByteBuf {
168 private final ByteBuf referenceCountDelegate;
169
170 PooledNonRetainedDuplicateByteBuf(ByteBuf referenceCountDelegate, AbstractByteBuf buffer) {
171 super(buffer);
172 this.referenceCountDelegate = referenceCountDelegate;
173 }
174
175 @Override
176 boolean isAccessible0() {
177 return referenceCountDelegate.isAccessible();
178 }
179
180 @Override
181 int refCnt0() {
182 return referenceCountDelegate.refCnt();
183 }
184
185 @Override
186 ByteBuf retain0() {
187 referenceCountDelegate.retain();
188 return this;
189 }
190
191 @Override
192 ByteBuf retain0(int increment) {
193 referenceCountDelegate.retain(increment);
194 return this;
195 }
196
197 @Override
198 ByteBuf touch0() {
199 referenceCountDelegate.touch();
200 return this;
201 }
202
203 @Override
204 ByteBuf touch0(Object hint) {
205 referenceCountDelegate.touch(hint);
206 return this;
207 }
208
209 @Override
210 boolean release0() {
211 return referenceCountDelegate.release();
212 }
213
214 @Override
215 boolean release0(int decrement) {
216 return referenceCountDelegate.release(decrement);
217 }
218
219 @Override
220 public ByteBuf duplicate() {
221 ensureAccessible();
222 return new PooledNonRetainedDuplicateByteBuf(referenceCountDelegate, this);
223 }
224
225 @Override
226 public ByteBuf retainedDuplicate() {
227 return PooledDuplicatedByteBuf.newInstance(unwrap(), this, readerIndex(), writerIndex());
228 }
229
230 @Override
231 public ByteBuf slice(int index, int length) {
232 checkIndex(index, length);
233 return new PooledNonRetainedSlicedByteBuf(referenceCountDelegate, unwrap(), index, length);
234 }
235
236 @Override
237 public ByteBuf retainedSlice() {
238 return retainedSlice(readerIndex(), readableBytes());
239 }
240
241 @Override
242 public ByteBuf retainedSlice(int index, int length) {
243 return PooledSlicedByteBuf.newInstance(unwrap(), this, index, length);
244 }
245 }
246
247 private static final class PooledNonRetainedSlicedByteBuf extends UnpooledSlicedByteBuf {
248 private final ByteBuf referenceCountDelegate;
249
250 PooledNonRetainedSlicedByteBuf(ByteBuf referenceCountDelegate,
251 AbstractByteBuf buffer, int index, int length) {
252 super(buffer, index, length);
253 this.referenceCountDelegate = referenceCountDelegate;
254 }
255
256 @Override
257 boolean isAccessible0() {
258 return referenceCountDelegate.isAccessible();
259 }
260
261 @Override
262 int refCnt0() {
263 return referenceCountDelegate.refCnt();
264 }
265
266 @Override
267 ByteBuf retain0() {
268 referenceCountDelegate.retain();
269 return this;
270 }
271
272 @Override
273 ByteBuf retain0(int increment) {
274 referenceCountDelegate.retain(increment);
275 return this;
276 }
277
278 @Override
279 ByteBuf touch0() {
280 referenceCountDelegate.touch();
281 return this;
282 }
283
284 @Override
285 ByteBuf touch0(Object hint) {
286 referenceCountDelegate.touch(hint);
287 return this;
288 }
289
290 @Override
291 boolean release0() {
292 return referenceCountDelegate.release();
293 }
294
295 @Override
296 boolean release0(int decrement) {
297 return referenceCountDelegate.release(decrement);
298 }
299
300 @Override
301 public ByteBuf duplicate() {
302 ensureAccessible();
303 return new PooledNonRetainedDuplicateByteBuf(referenceCountDelegate, unwrap())
304 .setIndex(idx(readerIndex()), idx(writerIndex()));
305 }
306
307 @Override
308 public ByteBuf retainedDuplicate() {
309 return PooledDuplicatedByteBuf.newInstance(unwrap(), this, idx(readerIndex()), idx(writerIndex()));
310 }
311
312 @Override
313 public ByteBuf slice(int index, int length) {
314 checkIndex(index, length);
315 return new PooledNonRetainedSlicedByteBuf(referenceCountDelegate, unwrap(), idx(index), length);
316 }
317
318 @Override
319 public ByteBuf retainedSlice() {
320 return retainedSlice(readerIndex(), readableBytes());
321 }
322
323 @Override
324 public ByteBuf retainedSlice(int index, int length) {
325 return PooledSlicedByteBuf.newInstance(unwrap(), this, idx(index), length);
326 }
327 }
328 }