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" );
@@ -83,14 +86,15 @@ public final class NettyResponseFuture<V> implements ListenableFuture<V> {
83
86
private static final AtomicIntegerFieldUpdater <NettyResponseFuture > contentProcessedField = AtomicIntegerFieldUpdater .newUpdater (NettyResponseFuture .class , "contentProcessed" );
84
87
@ SuppressWarnings ("rawtypes" )
85
88
private static final AtomicIntegerFieldUpdater <NettyResponseFuture > onThrowableCalledField = AtomicIntegerFieldUpdater .newUpdater (NettyResponseFuture .class , "onThrowableCalled" );
89
+ @ SuppressWarnings ("rawtypes" )
90
+ private static final AtomicReferenceFieldUpdater <NettyResponseFuture , TimeoutsHolder > timeoutsHolderField = AtomicReferenceFieldUpdater .newUpdater (NettyResponseFuture .class , TimeoutsHolder .class , "timeoutsHolder" );
86
91
87
92
// volatile where we need CAS ops
88
93
private volatile int redirectCount = 0 ;
89
94
private volatile int currentRetry = 0 ;
90
95
91
96
// volatile where we don't need CAS ops
92
97
private volatile long touch = unpreciseMillisTime ();
93
- private volatile TimeoutsHolder timeoutsHolder ;
94
98
private volatile ChannelState channelState = ChannelState .NEW ;
95
99
96
100
// state mutated only inside the event loop
@@ -280,9 +284,9 @@ public void setAsyncHandler(AsyncHandler<V> asyncHandler) {
280
284
}
281
285
282
286
public void cancelTimeouts () {
283
- if ( timeoutsHolder != null ) {
284
- timeoutsHolder . cancel ();
285
- timeoutsHolder = null ;
287
+ TimeoutsHolder ref = timeoutsHolderField . getAndSet ( this , null );
288
+ if ( ref != null ) {
289
+ ref . cancel () ;
286
290
}
287
291
}
288
292
@@ -319,11 +323,11 @@ public int incrementAndGetCurrentRedirectCount() {
319
323
}
320
324
321
325
public void setTimeoutsHolder (TimeoutsHolder timeoutsHolder ) {
322
- this . timeoutsHolder = timeoutsHolder ;
326
+ timeoutsHolderField . set ( this , timeoutsHolder ) ;
323
327
}
324
328
325
329
public TimeoutsHolder getTimeoutsHolder () {
326
- return timeoutsHolder ;
330
+ return timeoutsHolderField . get ( this ) ;
327
331
}
328
332
329
333
public boolean isInAuth () {
@@ -475,7 +479,7 @@ public String toString() {
475
479
",\n \t uri=" + getUri () + //
476
480
",\n \t keepAlive=" + keepAlive + //
477
481
",\n \t redirectCount=" + redirectCount + //
478
- ",\n \t timeoutsHolder=" + timeoutsHolder + //
482
+ ",\n \t timeoutsHolder=" + timeoutsHolderField . get ( this ) + //
479
483
",\n \t inAuth=" + inAuth + //
480
484
",\n \t statusReceived=" + statusReceived + //
481
485
",\n \t touch=" + touch + //
0 commit comments