FileDocCategorySizeDatePackage
AEMonitor.javaAPI DocAzureus 3.0.3.43946Wed Aug 02 09:10:46 BST 2006org.gudy.azureus2.core3.util

AEMonitor

public class AEMonitor extends AEMonSem
author
parg

Fields Summary
private int
dont_wait
private int
nests
private int
total_reserve
private int
total_release
protected Thread
owner
protected Thread
last_waiter
Constructors Summary
public AEMonitor(String _name)

	
	
	
					 
	
		super( _name, true );
	
Methods Summary
public voidenter()

		if ( DEBUG ){
			
			debugEntry();
		}				

		Thread	current_thread = Thread.currentThread();
		
		synchronized( this ){
			
			entry_count++;
			
			if ( owner == current_thread ){
				
				nests++;
				
			}else{
				
				if ( dont_wait == 0 ){

					try{
						waiting++;

						last_waiter	= current_thread;
						
						if ( waiting > 1 ){
							
							// System.out.println( "AEMonitor: " + name + " contended" );
						}
						
							// we can get spurious wakeups (see Object javadoc) so we need to guard against
							// their possibility
						
						int	spurious_count	= 0;
						
						while( true ){
							
							wait();
							
							if ( total_reserve == total_release ){
								
								spurious_count++;
	
								if ( spurious_count > 1024 ){
								
									Debug.out( "AEMonitor: spurious wakeup limit exceeded" );
									
									throw( new Throwable( "die die die" ));
									
								}else{
								
									Debug.out("AEMonitor: spurious wakeup, ignoring" );
								}					
							}else{
								
								break;
							}
						}
						
						total_reserve++;
						
					}catch( Throwable e ){

							// we know here that someone's got a finally clause to do the
							// balanced 'exit'. hence we should make it look as if we own it...
						
						waiting--;

						owner	= current_thread;
						
						Debug.out( "**** monitor interrupted ****" );
						
						throw( new RuntimeException("AEMonitor:interrupted" ));
						
					}finally{
						
						last_waiter = null;
					}
				}else{
					
					total_reserve++;
					
					dont_wait--;
				}
			
				owner	= current_thread;
			}
		}
	
public voidexit()

		try{
			synchronized( this ){

				if ( nests > 0 ){
					
					if ( DEBUG ){
						
						if ( owner != Thread.currentThread()){
						
							Debug.out( "nested exit but current thread not owner");
						}
					}
					
					nests--;
					
				}else{
					
					owner	= null;
					
					total_release++;
					
					if ( waiting != 0 ){

						waiting--;

						notify();

					}else{
						
						dont_wait++;
						
						if ( dont_wait > 1 ){
							
							Debug.out( "**** AEMonitor '" + name + "': multiple exit detected" );
						}
					}
				}
			}
			
		}finally{
		
			if ( DEBUG ){
				
				debugExit();
			}
		}
	
public static java.util.MapgetSynchronisedMap(java.util.Map m)

		return( Collections.synchronizedMap(m));
	
public booleanhasWaiters()

		synchronized( this ){
			
			return( waiting > 0 );
		}
	
public booleanisHeld()

		return( owner == Thread.currentThread());