1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.util;
17
18 import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
19
20 import io.netty.util.internal.ReferenceCountUpdater;
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<AbstractReferenceCounted>() {
33 @Override
34 protected AtomicIntegerFieldUpdater<AbstractReferenceCounted> updater() {
35 return AIF_UPDATER;
36 }
37 @Override
38 protected long unsafeOffset() {
39 return REFCNT_FIELD_OFFSET;
40 }
41 };
42
43
44 @SuppressWarnings({"unused", "FieldMayBeFinal"})
45 private volatile int refCnt = updater.initialValue();
46
47 @Override
48 public int refCnt() {
49 return updater.refCnt(this);
50 }
51
52
53
54
55 protected final void setRefCnt(int refCnt) {
56 updater.setRefCnt(this, refCnt);
57 }
58
59 @Override
60 public ReferenceCounted retain() {
61 return updater.retain(this);
62 }
63
64 @Override
65 public ReferenceCounted retain(int increment) {
66 return updater.retain(this, increment);
67 }
68
69 @Override
70 public ReferenceCounted touch() {
71 return touch(null);
72 }
73
74 @Override
75 public boolean release() {
76 return handleRelease(updater.release(this));
77 }
78
79 @Override
80 public boolean release(int decrement) {
81 return handleRelease(updater.release(this, decrement));
82 }
83
84 private boolean handleRelease(boolean result) {
85 if (result) {
86 deallocate();
87 }
88 return result;
89 }
90
91
92
93
94 protected abstract void deallocate();
95 }