1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty5.util;
17
18 import io.netty5.util.internal.ReferenceCountUpdater;
19
20 import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
21
22
23
24
25 public abstract class AbstractReferenceCounted implements ReferenceCounted {
26 private static final long REFCNT_FIELD_OFFSET =
27 ReferenceCountUpdater.getUnsafeOffset(AbstractReferenceCounted.class, "refCnt");
28 private static final AtomicIntegerFieldUpdater<AbstractReferenceCounted> AIF_UPDATER =
29 AtomicIntegerFieldUpdater.newUpdater(AbstractReferenceCounted.class, "refCnt");
30
31 private static final ReferenceCountUpdater<AbstractReferenceCounted> updater =
32 new ReferenceCountUpdater<>() {
33 @Override
34 protected AtomicIntegerFieldUpdater<AbstractReferenceCounted> updater() {
35 return AIF_UPDATER;
36 }
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 = updater.initialValue();
47
48 @Override
49 public int refCnt() {
50 return updater.refCnt(this);
51 }
52
53
54
55
56 protected final void setRefCnt(int refCnt) {
57 updater.setRefCnt(this, refCnt);
58 }
59
60 @Override
61 public ReferenceCounted retain() {
62 return updater.retain(this);
63 }
64
65 @Override
66 public ReferenceCounted retain(int increment) {
67 return updater.retain(this, increment);
68 }
69
70 @Override
71 public ReferenceCounted touch() {
72 return touch(null);
73 }
74
75 @Override
76 public boolean release() {
77 return handleRelease(updater.release(this));
78 }
79
80 @Override
81 public boolean release(int decrement) {
82 return handleRelease(updater.release(this, decrement));
83 }
84
85 private boolean handleRelease(boolean result) {
86 if (result) {
87 deallocate();
88 }
89 return result;
90 }
91
92
93
94
95 protected abstract void deallocate();
96 }