24
24
import java .lang .ref .WeakReference ;
25
25
import java .util .concurrent .ConcurrentHashMap ;
26
26
import java .util .concurrent .ConcurrentMap ;
27
+ import java .util .concurrent .atomic .AtomicBoolean ;
27
28
import java .util .logging .Level ;
28
29
import java .util .logging .LogRecord ;
29
30
import java .util .logging .Logger ;
@@ -54,15 +55,13 @@ final class ManagedChannelOrphanWrapper extends ForwardingManagedChannel {
54
55
55
56
@ Override
56
57
public ManagedChannel shutdown () {
57
- phantom .shutdown = true ;
58
- phantom .clear ();
58
+ phantom .clearSafely ();
59
59
return super .shutdown ();
60
60
}
61
61
62
62
@ Override
63
63
public ManagedChannel shutdownNow () {
64
- phantom .shutdown = true ;
65
- phantom .clear ();
64
+ phantom .clearSafely ();
66
65
return super .shutdownNow ();
67
66
}
68
67
@@ -81,7 +80,7 @@ static final class ManagedChannelReference extends WeakReference<ManagedChannelO
81
80
82
81
private final String channelStr ;
83
82
private final Reference <RuntimeException > allocationSite ;
84
- private volatile boolean shutdown ;
83
+ private final AtomicBoolean shutdown = new AtomicBoolean () ;
85
84
86
85
ManagedChannelReference (
87
86
ManagedChannelOrphanWrapper orphanable ,
@@ -113,6 +112,15 @@ public void clear() {
113
112
cleanQueue (refqueue );
114
113
}
115
114
115
+ /**
116
+ * Safe to call concurrently.
117
+ */
118
+ private void clearSafely () {
119
+ if (!shutdown .getAndSet (true )) {
120
+ clear ();
121
+ }
122
+ }
123
+
116
124
// avoid reentrancy
117
125
private void clearInternal () {
118
126
super .clear ();
@@ -135,7 +143,7 @@ static int cleanQueue(ReferenceQueue<ManagedChannelOrphanWrapper> refqueue) {
135
143
while ((ref = (ManagedChannelReference ) refqueue .poll ()) != null ) {
136
144
RuntimeException maybeAllocationSite = ref .allocationSite .get ();
137
145
ref .clearInternal (); // technically the reference is gone already.
138
- if (!ref .shutdown ) {
146
+ if (!ref .shutdown . get () ) {
139
147
orphanedChannels ++;
140
148
Level level = Level .SEVERE ;
141
149
if (logger .isLoggable (level )) {
0 commit comments