<s> package org . eclipse . jdt . internal . compiler ; import org . eclipse . jdt . internal . compiler . ast . CompilationUnitDeclaration ; import org . eclipse . jdt . internal . compiler . util . Messages ; public class ProcessTaskManager implements Runnable { Compiler compiler ; private int unitIndex ; private Thread processingThread ; CompilationUnitDeclaration unitToProcess ; private Throwable caughtException ; volatile int currentIndex , availableIndex , size , sleepCount ; CompilationUnitDeclaration [ ] units ; public static final int PROCESSED_QUEUE_SIZE = 12 ; public ProcessTaskManager ( Compiler compiler ) { this . compiler = compiler ; this . unitIndex = 0 ; this . currentIndex = 0 ; this . availableIndex = 0 ; this . size = PROCESSED_QUEUE_SIZE ; this . sleepCount = 0 ; this . units = new CompilationUnitDeclaration [ this . size ] ; synchronized ( this ) { this . processingThread = new Thread ( this , "" ) ; this . processingThread . setDaemon ( true ) ; this . processingThread . start ( ) ; } } private synchronized void addNextUnit ( CompilationUnitDeclaration newElement ) { while ( this . units [ this . availableIndex ] != null ) { this . sleepCount = 1 ; try { wait ( 250 ) ; } catch ( InterruptedException ignore ) { } this . sleepCount = 0 ; } this . units [ this . availableIndex ++ ] = newElement ; if ( this . availableIndex >= this . size ) this . availableIndex = 0 ; if ( this . sleepCount <= - 1 ) notify ( ) ; } public CompilationUnitDeclaration removeNextUnit ( ) throws Error { CompilationUnitDeclaration next = null ; boolean yield = false ; synchronized ( this ) { next = this . units [ this . currentIndex ] ; if ( next == null || this . caughtException != null ) { do { if ( this . processingThread == null ) { if ( this . caughtException != null ) { if ( this . caughtException instanceof Error ) throw ( Error ) this . caughtException ; throw ( RuntimeException ) this . caughtException ; } return null ; } this . sleepCount = - 1 ; try { wait ( 100 ) ; } catch ( InterruptedException ignore ) { } this . sleepCount = 0 ; next = this . units [ this . currentIndex ] ; } while ( next == null ) ; } this . units [ this . currentIndex ++ ] = null ; if ( this . currentIndex >= this . size ) this . currentIndex = 0 ; if ( this . sleepCount >= 1 && ++ this . sleepCount > 4 ) { notify ( ) ; yield = this . sleepCount > 8 ; } } if ( yield ) Thread . yield ( ) ; return next ; } public void run ( ) { while ( this . processingThread != null ) { this . unitToProcess = null ; int index = - 1 ; try { synchronized ( this ) { if ( this . processingThread == null ) return ; this . unitToProcess = this . compiler . getUnitToProcess ( this . unitIndex ) ; if ( this . unitToProcess == null ) { this . processingThread = null ; return ; } index = this . unitIndex ++ ; } try { this . compiler . reportProgress ( Messages . bind ( Messages . compilation_processing , new String ( this . unitToProcess . getFileName ( ) ) ) ) ; if ( this . compiler . options . verbose ) this . compiler . out . println ( Messages . bind ( Messages . compilation_process , new String [ ] { String . valueOf ( index + 1 ) , String . valueOf ( this . compiler . totalUnits ) , new String ( this . unitToProcess . getFileName ( ) ) } ) ) ; this . compiler . process ( this . unitToProcess , index ) ; } finally { if ( this . unitToProcess != null ) this . unitToProcess . cleanUp ( ) ; } addNextUnit ( this . unitToProcess ) ; } catch ( Error e ) { synchronized ( this ) { this . processingThread = null ; this . caughtException = e ; } return ; } catch ( RuntimeException e ) { synchronized ( this ) { this . processingThread = null ; this . caughtException = e ; } return ; } } } public void shutdown ( ) { try { Thread t = null ; synchronized ( this ) { if ( this . processingThread != null ) { t = this . processingThread ; this . processingThread = null ; notifyAll ( ) ; } } if ( t != null ) t . join ( 250 ) ; } catch ( InterruptedException ignored ) { } } } </s>