2424import java .util .concurrent .TimeUnit ;
2525import java .util .concurrent .TimeoutException ;
2626import java .util .concurrent .atomic .AtomicIntegerFieldUpdater ;
27+ import java .util .concurrent .atomic .AtomicReferenceFieldUpdater ;
2728
2829import org .asynchttpclient .AsyncHandler ;
2930import org .asynchttpclient .ListenableFuture ;
@@ -70,6 +71,8 @@ public final class NettyResponseFuture<V> implements ListenableFuture<V> {
7071private volatile int contentProcessed =0 ;
7172@ SuppressWarnings ("unused" )
7273private volatile int onThrowableCalled =0 ;
74+ @ SuppressWarnings ("unused" )
75+ private volatile TimeoutsHolder timeoutsHolder ;
7376
7477@ SuppressWarnings ("rawtypes" )
7578private static final AtomicIntegerFieldUpdater <NettyResponseFuture >isDoneField =AtomicIntegerFieldUpdater .newUpdater (NettyResponseFuture .class ,"isDone" );
@@ -85,14 +88,15 @@ public final class NettyResponseFuture<V> implements ListenableFuture<V> {
8588private static final AtomicIntegerFieldUpdater <NettyResponseFuture >contentProcessedField =AtomicIntegerFieldUpdater .newUpdater (NettyResponseFuture .class ,"contentProcessed" );
8689@ SuppressWarnings ("rawtypes" )
8790private 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" );
8893
8994// volatile where we need CAS ops
9095private volatile int redirectCount =0 ;
9196private volatile int currentRetry =0 ;
9297
9398// volatile where we don't need CAS ops
9499private volatile long touch =unpreciseMillisTime ();
95- private volatile TimeoutsHolder timeoutsHolder ;
96100private volatile ChannelState channelState =ChannelState .NEW ;
97101
98102// state mutated only inside the event loop
@@ -282,9 +286,9 @@ public void setAsyncHandler(AsyncHandler<V> asyncHandler) {
282286 }
283287
284288public 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 () ;
288292 }
289293 }
290294
@@ -321,11 +325,11 @@ public int incrementAndGetCurrentRedirectCount() {
321325 }
322326
323327public void setTimeoutsHolder (TimeoutsHolder timeoutsHolder ) {
324- this . timeoutsHolder = timeoutsHolder ;
328+ timeoutsHolderField . set ( this , timeoutsHolder ) ;
325329 }
326330
327331public TimeoutsHolder getTimeoutsHolder () {
328- return timeoutsHolder ;
332+ return timeoutsHolderField . get ( this ) ;
329333 }
330334
331335public boolean isInAuth () {
@@ -481,7 +485,7 @@ public String toString() {
481485",\n \t uri=" +getUri () +//
482486",\n \t keepAlive=" +keepAlive +//
483487",\n \t redirectCount=" +redirectCount +//
484- ",\n \t timeoutsHolder=" +timeoutsHolder +//
488+ ",\n \t timeoutsHolder=" +timeoutsHolderField . get ( this ) +//
485489",\n \t inAuth=" +inAuth +//
486490",\n \t statusReceived=" +statusReceived +//
487491",\n \t touch=" +touch +//