final void deregisterWorker ( ForkJoinWorkerThread wt , Throwable ex ) { Mutex lock = this . lock ; WorkQueue w = null ; if ( wt != null && ( w = wt . workQueue ) != null ) { w . runState = - 1 ; // ensure runState is set stealCount . getAndAdd ( w . totalSteals + w . nsteals ) ; int idx = w . poolIndex ; lock . lock ( ) ; try { // remove record from array WorkQueue [ ] ws = workQueues ; if ( ws != null && idx >= 0 && idx < ws . length && ws [ idx ] == w ) ws [ idx ] = null ; } finally { lock . unlock ( ) ; } } long c ; // adjust ctl counts do { } while ( ! U . compareAndSwapLong ( this , CTL , c = ctl , ( ( ( c - AC_UNIT ) & AC_MASK ) | ( ( c - TC_UNIT ) & TC_MASK ) | ( c & ~ ( AC_MASK | TC_MASK ) ) ) ) ) ; if ( ! tryTerminate ( false , false ) && w != null ) { w . cancelAll ( ) ; // cancel remaining tasks if ( w . array != null ) // suppress signal if never ran signalWork ( ) ; // wake up or create replacement if ( ex == null ) // help clean refs on way out ForkJoinTask . helpExpungeStaleExceptions ( ) ; } if ( ex != null ) // rethrow U . throwException ( ex ) ; }
Final callback from terminating worker as well as upon failure to construct or start a worker in addWorker . Removes record of worker from array and adjusts counts . If pool is shutting down tries to complete termination .