final void deregisterWorker ( ForkJoinWorkerThread wt , Throwable ex ) { WorkQueue w = null ; if ( wt != null && ( w = wt . workQueue ) != null ) { WorkQueue [ ] ws ; // remove index from array int idx = w . config & SMASK ; int rs = lockRunState ( ) ; if ( ( ws = workQueues ) != null && ws . length > idx && ws [ idx ] == w ) ws [ idx ] = null ; unlockRunState ( rs , rs & ~ RSLOCK ) ; } long c ; // decrement counts do { } while ( ! U . compareAndSwapLong ( this , CTL , c = ctl , ( ( AC_MASK & ( c - AC_UNIT ) ) | ( TC_MASK & ( c - TC_UNIT ) ) | ( SP_MASK & c ) ) ) ) ; if ( w != null ) { w . qlock = - 1 ; // ensure set w . transferStealCount ( this ) ; w . cancelAll ( ) ; // cancel remaining tasks } for ( ; ; ) { // possibly replace WorkQueue [ ] ws ; int m , sp ; if ( tryTerminate ( false , false ) || w == null || w . array == null || ( runState & STOP ) != 0 || ( ws = workQueues ) == null || ( m = ws . length - 1 ) < 0 ) // already terminating break ; if ( ( sp = ( int ) ( c = ctl ) ) != 0 ) { // wake up replacement if ( tryRelease ( c , ws [ sp & m ] , AC_UNIT ) ) break ; } else if ( ex != null && ( c & ADD_WORKER ) != 0L ) { tryAddWorker ( c ) ; // create replacement break ; } else // don't need replacement break ; } if ( ex == null ) // help clean on way out ForkJoinTask . helpExpungeStaleExceptions ( ) ; else // rethrow ForkJoinTask . rethrow ( ex ) ; }
Final callback from terminating worker as well as upon failure to construct or start a worker . Removes record of worker from array and adjusts counts . If pool is shutting down tries to complete termination .