24
24
import java .util .concurrent .TimeUnit ;
25
25
import java .util .concurrent .TimeoutException ;
26
26
import java .util .concurrent .atomic .AtomicIntegerFieldUpdater ;
27
+ import java .util .concurrent .atomic .AtomicReferenceFieldUpdater ;
27
28
28
29
import org .asynchttpclient .AsyncHandler ;
29
30
import org .asynchttpclient .ListenableFuture ;
@@ -70,6 +71,8 @@ public final class NettyResponseFuture<V> implements ListenableFuture<V> {
70
71
private volatile int contentProcessed = 0 ;
71
72
@ SuppressWarnings ("unused" )
72
73
private volatile int onThrowableCalled = 0 ;
74
+ @ SuppressWarnings ("unused" )
75
+ private volatile TimeoutsHolder timeoutsHolder ;
73
76
74
77
@ SuppressWarnings ("rawtypes" )
75
78
private static final AtomicIntegerFieldUpdater <NettyResponseFuture > isDoneField = AtomicIntegerFieldUpdater .newUpdater (NettyResponseFuture .class , "isDone" );
@@ -85,14 +88,15 @@ public final class NettyResponseFuture<V> implements ListenableFuture<V> {
85
88
private static final AtomicIntegerFieldUpdater <NettyResponseFuture > contentProcessedField = AtomicIntegerFieldUpdater .newUpdater (NettyResponseFuture .class , "contentProcessed" );
86
89
@ SuppressWarnings ("rawtypes" )
87
90
private static final AtomicIntegerFieldUpdater <NettyResponseFuture > onThrowableCalledField = AtomicIntegerFieldUpdater .newUpdater (NettyResponseFuture .class , "onThrowableCalled" );
91
+ @ SuppressWarnings ("rawtypes" )
92
+ private static final AtomicReferenceFieldUpdater <NettyResponseFuture , TimeoutsHolder > timeoutsHolderField = AtomicReferenceFieldUpdater .newUpdater (NettyResponseFuture .class , TimeoutsHolder .class , "timeoutsHolder" );
88
93
89
94
// volatile where we need CAS ops
90
95
private volatile int redirectCount = 0 ;
91
96
private volatile int currentRetry = 0 ;
92
97
93
98
// volatile where we don't need CAS ops
94
99
private volatile long touch = unpreciseMillisTime ();
95
- private volatile TimeoutsHolder timeoutsHolder ;
96
100
private volatile ChannelState channelState = ChannelState .NEW ;
97
101
98
102
// state mutated only inside the event loop
@@ -282,9 +286,9 @@ public void setAsyncHandler(AsyncHandler<V> asyncHandler) {
282
286
}
283
287
284
288
public void cancelTimeouts () {
285
- if ( timeoutsHolder != null ) {
286
- timeoutsHolder . cancel ();
287
- timeoutsHolder = null ;
289
+ TimeoutsHolder ref = timeoutsHolderField . getAndSet ( this , null );
290
+ if ( ref != null ) {
291
+ ref . cancel () ;
288
292
}
289
293
}
290
294
@@ -321,11 +325,11 @@ public int incrementAndGetCurrentRedirectCount() {
321
325
}
322
326
323
327
public void setTimeoutsHolder (TimeoutsHolder timeoutsHolder ) {
324
- this . timeoutsHolder = timeoutsHolder ;
328
+ timeoutsHolderField . set ( this , timeoutsHolder ) ;
325
329
}
326
330
327
331
public TimeoutsHolder getTimeoutsHolder () {
328
- return timeoutsHolder ;
332
+ return timeoutsHolderField . get ( this ) ;
329
333
}
330
334
331
335
public boolean isInAuth () {
@@ -481,7 +485,7 @@ public String toString() {
481
485
",\n \t uri=" + getUri () + //
482
486
",\n \t keepAlive=" + keepAlive + //
483
487
",\n \t redirectCount=" + redirectCount + //
484
- ",\n \t timeoutsHolder=" + timeoutsHolder + //
488
+ ",\n \t timeoutsHolder=" + timeoutsHolderField . get ( this ) + //
485
489
",\n \t inAuth=" + inAuth + //
486
490
",\n \t statusReceived=" + statusReceived + //
487
491
",\n \t touch=" + touch + //
0 commit comments