private static void complete ( AbstractFuture < ? > future ) { boolean maskExecutorExceptions = future . maskExecutorExceptions ; Listener next = null ; outer : while ( true ) { future . releaseWaiters ( ) ; // We call this before the listeners in order to avoid needing to manage a separate stack data // structure for them. // afterDone() should be generally fast and only used for cleanup work... but in theory can // also be recursive and create StackOverflowErrors future . afterDone ( ) ; // push the current set of listeners onto next next = future . clearListeners ( next ) ; future = null ; while ( next != null ) { Listener curr = next ; next = next . next ; Runnable task = curr . task ; if ( task instanceof AbstractFuture . SetFuture ) { AbstractFuture . SetFuture < ? > setFuture = ( AbstractFuture . SetFuture ) task ; // We unwind setFuture specifically to avoid StackOverflowErrors in the case of long // chains of SetFutures // Handling this special case is important because there is no way to pass an executor to // setFuture, so a user couldn't break the chain by doing this themselves. It is also // potentially common if someone writes a recursive Futures.transformAsync transformer. future = setFuture . owner ; if ( future . value == setFuture ) { Object valueToSet = getFutureValue ( setFuture . future ) ; if ( ATOMIC_HELPER . casValue ( future , setFuture , valueToSet ) ) { continue outer ; } } // other wise the future we were trying to set is already done. } else { executeListener ( task , curr . executor , maskExecutorExceptions ) ; } } break ; } }
Unblocks all threads and runs all listeners .