View Javadoc
1   /*
2    * Copyright 2016 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.buffer;
17  
18  
19  import io.netty.util.ResourceLeakTracker;
20  import io.netty.util.internal.ObjectUtil;
21  
22  import java.nio.ByteOrder;
23  
24  class SimpleLeakAwareCompositeByteBuf extends WrappedCompositeByteBuf {
25  
26      final ResourceLeakTracker<ByteBuf> leak;
27  
28      SimpleLeakAwareCompositeByteBuf(CompositeByteBuf wrapped, ResourceLeakTracker<ByteBuf> leak) {
29          super(wrapped);
30          this.leak = ObjectUtil.checkNotNull(leak, "leak");
31      }
32  
33      @Override
34      public boolean release() {
35          // Call unwrap() before just in case that super.release() will change the ByteBuf instance that is returned
36          // by unwrap().
37          ByteBuf unwrapped = unwrap();
38          if (super.release()) {
39              closeLeak(unwrapped);
40              return true;
41          }
42          return false;
43      }
44  
45      @Override
46      public boolean release(int decrement) {
47          // Call unwrap() before just in case that super.release() will change the ByteBuf instance that is returned
48          // by unwrap().
49          ByteBuf unwrapped = unwrap();
50          if (super.release(decrement)) {
51              closeLeak(unwrapped);
52              return true;
53          }
54          return false;
55      }
56  
57      private void closeLeak(ByteBuf trackedByteBuf) {
58          // Close the ResourceLeakTracker with the tracked ByteBuf as argument. This must be the same that was used when
59          // calling DefaultResourceLeak.track(...).
60          boolean closed = leak.close(trackedByteBuf);
61          assert closed;
62      }
63  
64      @Override
65      public ByteBuf order(ByteOrder endianness) {
66          if (order() == endianness) {
67              return this;
68          } else {
69              return newLeakAwareByteBuf(super.order(endianness));
70          }
71      }
72  
73      @Override
74      public ByteBuf slice() {
75          return newLeakAwareByteBuf(super.slice());
76      }
77  
78      @Override
79      public ByteBuf slice(int index, int length) {
80          return newLeakAwareByteBuf(super.slice(index, length));
81      }
82  
83      @Override
84      public ByteBuf duplicate() {
85          return newLeakAwareByteBuf(super.duplicate());
86      }
87  
88      @Override
89      public ByteBuf readSlice(int length) {
90          return newLeakAwareByteBuf(super.readSlice(length));
91      }
92  
93      private SimpleLeakAwareByteBuf newLeakAwareByteBuf(ByteBuf wrapped) {
94          return newLeakAwareByteBuf(wrapped, unwrap(), leak);
95      }
96  
97      protected SimpleLeakAwareByteBuf newLeakAwareByteBuf(
98              ByteBuf wrapped, ByteBuf trackedByteBuf, ResourceLeakTracker<ByteBuf> leakTracker) {
99          return new SimpleLeakAwareByteBuf(wrapped, trackedByteBuf, leakTracker);
100     }
101 }