1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.netty.buffer;
18
19 import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
20
21 import io.netty.util.internal.ReferenceCountUpdater;
22
23
24
25
26 public abstract class AbstractReferenceCountedByteBuf extends AbstractByteBuf {
27 private static final long REFCNT_FIELD_OFFSET =
28 ReferenceCountUpdater.getUnsafeOffset(AbstractReferenceCountedByteBuf.class, "refCnt");
29 private static final AtomicIntegerFieldUpdater<AbstractReferenceCountedByteBuf> AIF_UPDATER =
30 AtomicIntegerFieldUpdater.newUpdater(AbstractReferenceCountedByteBuf.class, "refCnt");
31
32 private static final ReferenceCountUpdater<AbstractReferenceCountedByteBuf> updater =
33 new ReferenceCountUpdater<AbstractReferenceCountedByteBuf>() {
34 @Override
35 protected AtomicIntegerFieldUpdater<AbstractReferenceCountedByteBuf> updater() {
36 return AIF_UPDATER;
37 }
38 @Override
39 protected long unsafeOffset() {
40 return REFCNT_FIELD_OFFSET;
41 }
42 };
43
44
45 @SuppressWarnings({"unused", "FieldMayBeFinal"})
46 private volatile int refCnt;
47
48 protected AbstractReferenceCountedByteBuf(int maxCapacity) {
49 super(maxCapacity);
50 updater.setInitialValue(this);
51 }
52
53 @Override
54 boolean isAccessible() {
55
56
57 return updater.isLiveNonVolatile(this);
58 }
59
60 @Override
61 public int refCnt() {
62 return updater.refCnt(this);
63 }
64
65
66
67
68 protected final void setRefCnt(int refCnt) {
69 updater.setRefCnt(this, refCnt);
70 }
71
72
73
74
75 protected final void resetRefCnt() {
76 updater.resetRefCnt(this);
77 }
78
79 @Override
80 public ByteBuf retain() {
81 return updater.retain(this);
82 }
83
84 @Override
85 public ByteBuf retain(int increment) {
86 return updater.retain(this, increment);
87 }
88
89 @Override
90 public ByteBuf touch() {
91 return this;
92 }
93
94 @Override
95 public ByteBuf touch(Object hint) {
96 return this;
97 }
98
99 @Override
100 public boolean release() {
101 return handleRelease(updater.release(this));
102 }
103
104 @Override
105 public boolean release(int decrement) {
106 return handleRelease(updater.release(this, decrement));
107 }
108
109 private boolean handleRelease(boolean result) {
110 if (result) {
111 deallocate();
112 }
113 return result;
114 }
115
116
117
118
119 protected abstract void deallocate();
120 }