/*
 * Written by Doug Lea with assistance from members of JCP JSR-166
 * Expert Group and released to the public domain, as explained at
 * http://creativecommons.org/licenses/publicdomain
 * Other contributors include Andrew Wright, Jeffrey Hayes, 
 * Pat Fisher, Mike Judd. 
 */


import junit.framework.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.*;
import java.io.*;

public class AbstractQueuedSynchronizerTest extends JSR166TestCase {
    public static void main(String[] args) {
        junit.textui.TestRunner.run (suite());
    }
    public static Test suite() {
        return new TestSuite(AbstractQueuedSynchronizerTest.class);
    }

    /**
     * A simple mutex class, adapted from the
     * AbstractQueuedSynchronizer javadoc.  Exclusive acquire tests
     * exercise this as a sample user extension.  Other
     * methods/features of AbstractQueuedSynchronizerTest are tested
     * via other test classes, including those for ReentrantLock,
     * ReentrantReadWriteLock, and Semaphore
     */
    static class Mutex extends AbstractQueuedSynchronizer {
        public boolean isHeldExclusively() { return getState() == 1; }
        
        public boolean tryAcquire(int acquires) {
            assertTrue(acquires == 1); 
            return compareAndSetState(0, 1);
        }
        
        public boolean tryRelease(int releases) {
            if (getState() == 0) throw new IllegalMonitorStateException();
            setState(0);
            return true;
        }
        
        public AbstractQueuedSynchronizer.ConditionObject newCondition() { return new AbstractQueuedSynchronizer.ConditionObject(); }

    }

    
    /**
     * A simple latch class, to test shared mode.
     */
    static class BooleanLatch extends AbstractQueuedSynchronizer { 
        public boolean isSignalled() { return getState() != 0; }

        public int tryAcquireShared(int ignore) {
            return isSignalled()? 1 : -1;
        }
        
        public boolean tryReleaseShared(int ignore) {
            setState(1);
            return true;
        }
    }

    /**
     * A runnable calling acquireInterruptibly
     */
    class InterruptibleSyncRunnable implements Runnable {
        final Mutex sync;
        InterruptibleSyncRunnable(Mutex l) { sync = l; }
        public void run() {
            try {
                sync.acquireInterruptibly(1);
            } catch(InterruptedException success){}
        }
    }


    /**
     * A runnable calling acquireInterruptibly that expects to be
     * interrupted
     */
    class InterruptedSyncRunnable implements Runnable {
        final Mutex sync;
        InterruptedSyncRunnable(Mutex l) { sync = l; }
        public void run() {
            try {
                sync.acquireInterruptibly(1);
                threadShouldThrow();
            } catch(InterruptedException success){}
        }
    }

    /**
     * isHeldExclusively is false upon construction
     */
    public void testIsHeldExclusively() { 
	Mutex rl = new Mutex();
        assertFalse(rl.isHeldExclusively());
    }
    
    /**
     * acquiring released sync succeeds
     */
    public void testAcquire() { 
	Mutex rl = new Mutex();
        rl.acquire(1);
        assertTrue(rl.isHeldExclusively());
        rl.release(1);
        assertFalse(rl.isHeldExclusively());
    }

    /**
     * tryAcquire on an released sync succeeds
     */
    public void testTryAcquire() { 
	Mutex rl = new Mutex();
        assertTrue(rl.tryAcquire(1));
        assertTrue(rl.isHeldExclusively());
        rl.release(1);
    }

    /**
     * hasQueuedThreads reports whether there are waiting threads
     */
    public void testhasQueuedThreads() { 
	final Mutex sync = new Mutex();
        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
        try {
            assertFalse(sync.hasQueuedThreads());
            sync.acquire(1);
            t1.start();
            Thread.sleep(SHORT_DELAY_MS);
            assertTrue(sync.hasQueuedThreads());
            t2.start();
            Thread.sleep(SHORT_DELAY_MS);
            assertTrue(sync.hasQueuedThreads());
            t1.interrupt();
            Thread.sleep(SHORT_DELAY_MS);
            assertTrue(sync.hasQueuedThreads());
            sync.release(1);
            Thread.sleep(SHORT_DELAY_MS);
            assertFalse(sync.hasQueuedThreads());
            t1.join();
            t2.join();
        } catch(Exception e){
            unexpectedException();
        }
    } 

    /**
     * isQueued(null) throws NPE
     */
    public void testIsQueuedNPE() { 
	final Mutex sync = new Mutex();
        try {
            sync.isQueued(null);
            shouldThrow();
        } catch (NullPointerException success) {
        }
    }

    /**
     * isQueued reports whether a thread is queued.
     */
    public void testIsQueued() { 
	final Mutex sync = new Mutex();
        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
        try {
            assertFalse(sync.isQueued(t1));
            assertFalse(sync.isQueued(t2));
            sync.acquire(1);
            t1.start();
            Thread.sleep(SHORT_DELAY_MS);
            assertTrue(sync.isQueued(t1));
            t2.start();
            Thread.sleep(SHORT_DELAY_MS);
            assertTrue(sync.isQueued(t1));
            assertTrue(sync.isQueued(t2));
            t1.interrupt();
            Thread.sleep(SHORT_DELAY_MS);
            assertFalse(sync.isQueued(t1));
            assertTrue(sync.isQueued(t2));
            sync.release(1);
            Thread.sleep(SHORT_DELAY_MS);
            assertFalse(sync.isQueued(t1));
            Thread.sleep(SHORT_DELAY_MS);
            assertFalse(sync.isQueued(t2));
            t1.join();
            t2.join();
        } catch(Exception e){
            unexpectedException();
        }
    } 

    /**
     * getFirstQueuedThread returns first waiting thread or null if none
     */
    public void testGetFirstQueuedThread() { 
	final Mutex sync = new Mutex();
        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
        try {
            assertNull(sync.getFirstQueuedThread());
            sync.acquire(1);
            t1.start();
            Thread.sleep(SHORT_DELAY_MS);
            assertEquals(t1, sync.getFirstQueuedThread());
            t2.start();
            Thread.sleep(SHORT_DELAY_MS);
            assertEquals(t1, sync.getFirstQueuedThread());
            t1.interrupt();
            Thread.sleep(SHORT_DELAY_MS);
            Thread.sleep(SHORT_DELAY_MS);
            assertEquals(t2, sync.getFirstQueuedThread());
            sync.release(1);
            Thread.sleep(SHORT_DELAY_MS);
            assertNull(sync.getFirstQueuedThread());
            t1.join();
            t2.join();
        } catch(Exception e){
            unexpectedException();
        }
    } 


    /**
     * hasContended reports false if no thread has ever blocked, else true
     */
    public void testHasContended() { 
	final Mutex sync = new Mutex();
        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
        try {
            assertFalse(sync.hasContended());
            sync.acquire(1);
            t1.start();
            Thread.sleep(SHORT_DELAY_MS);
            assertTrue(sync.hasContended());
            t2.start();
            Thread.sleep(SHORT_DELAY_MS);
            assertTrue(sync.hasContended());
            t1.interrupt();
            Thread.sleep(SHORT_DELAY_MS);
            assertTrue(sync.hasContended());
            sync.release(1);
            Thread.sleep(SHORT_DELAY_MS);
            assertTrue(sync.hasContended());
            t1.join();
            t2.join();
        } catch(Exception e){
            unexpectedException();
        }
    } 

    /**
     * getQueuedThreads includes waiting threads
     */
    public void testGetQueuedThreads() { 
	final Mutex sync = new Mutex();
        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
        try {
            assertTrue(sync.getQueuedThreads().isEmpty());
            sync.acquire(1);
            assertTrue(sync.getQueuedThreads().isEmpty());
            t1.start();
            Thread.sleep(SHORT_DELAY_MS);
            assertTrue(sync.getQueuedThreads().contains(t1));
            t2.start();
            Thread.sleep(SHORT_DELAY_MS);
            assertTrue(sync.getQueuedThreads().contains(t1));
            assertTrue(sync.getQueuedThreads().contains(t2));
            t1.interrupt();
            Thread.sleep(SHORT_DELAY_MS);
            assertFalse(sync.getQueuedThreads().contains(t1));
            assertTrue(sync.getQueuedThreads().contains(t2));
            sync.release(1);
            Thread.sleep(SHORT_DELAY_MS);
            assertTrue(sync.getQueuedThreads().isEmpty());
            t1.join();
            t2.join();
        } catch(Exception e){
            unexpectedException();
        }
    } 

    /**
     * getExclusiveQueuedThreads includes waiting threads
     */
    public void testGetExclusiveQueuedThreads() { 
	final Mutex sync = new Mutex();
        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
        try {
            assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
            sync.acquire(1);
            assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
            t1.start();
            Thread.sleep(SHORT_DELAY_MS);
            assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
            t2.start();
            Thread.sleep(SHORT_DELAY_MS);
            assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
            assertTrue(sync.getExclusiveQueuedThreads().contains(t2));
            t1.interrupt();
            Thread.sleep(SHORT_DELAY_MS);
            assertFalse(sync.getExclusiveQueuedThreads().contains(t1));
            assertTrue(sync.getExclusiveQueuedThreads().contains(t2));
            sync.release(1);
            Thread.sleep(SHORT_DELAY_MS);
            assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
            t1.join();
            t2.join();
        } catch(Exception e){
            unexpectedException();
        }
    } 

    /**
     * getSharedQueuedThreads does not include exclusively waiting threads
     */
    public void testGetSharedQueuedThreads() { 
	final Mutex sync = new Mutex();
        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
        try {
            assertTrue(sync.getSharedQueuedThreads().isEmpty());
            sync.acquire(1);
            assertTrue(sync.getSharedQueuedThreads().isEmpty());
            t1.start();
            Thread.sleep(SHORT_DELAY_MS);
            assertTrue(sync.getSharedQueuedThreads().isEmpty());
            t2.start();
            Thread.sleep(SHORT_DELAY_MS);
            assertTrue(sync.getSharedQueuedThreads().isEmpty());
            t1.interrupt();
            Thread.sleep(SHORT_DELAY_MS);
            assertTrue(sync.getSharedQueuedThreads().isEmpty());
            sync.release(1);
            Thread.sleep(SHORT_DELAY_MS);
            assertTrue(sync.getSharedQueuedThreads().isEmpty());
            t1.join();
            t2.join();
        } catch(Exception e){
            unexpectedException();
        }
    } 

    /**
     * tryAcquireNanos is interruptible.
     */
    public void testInterruptedException2() { 
	final Mutex sync = new Mutex();
	sync.acquire(1);
	Thread t = new Thread(new Runnable() {
                public void run() {
                    try {
			sync.tryAcquireNanos(1, MEDIUM_DELAY_MS * 1000 * 1000);
			threadShouldThrow();
		    } catch(InterruptedException success){}
		}
	    });
        try {
            t.start();
            t.interrupt();
        } catch(Exception e){
            unexpectedException();
        }
    }


    /**
     * TryAcquire on exclusively held sync fails
     */
    public void testTryAcquireWhenSynced() { 
	final Mutex sync = new Mutex();
	sync.acquire(1);
	Thread t = new Thread(new Runnable() {
                public void run() {
                    threadAssertFalse(sync.tryAcquire(1));
		}
	    });
        try {
            t.start();
            t.join();
            sync.release(1);
        } catch(Exception e){
            unexpectedException();
        }
    } 

    /**
     * tryAcquireNanos on an exclusively held sync times out
     */
    public void testAcquireNanos_Timeout() { 
	final Mutex sync = new Mutex();
	sync.acquire(1);
	Thread t = new Thread(new Runnable() {
                public void run() {
		    try {
                        threadAssertFalse(sync.tryAcquireNanos(1, 1000 * 1000));
                    } catch (Exception ex) {
                        threadUnexpectedException();
                    }
		}
	    });
        try {
            t.start();
            t.join();
            sync.release(1);
        } catch(Exception e){
            unexpectedException();
        }
    } 
    
   
    /**
     * getState is true when acquired and false when not
     */
    public void testGetState() {
	final Mutex sync = new Mutex();
	sync.acquire(1);
	assertTrue(sync.isHeldExclusively());
	sync.release(1);
	assertFalse(sync.isHeldExclusively());
	Thread t = new Thread(new Runnable() { 
		public void run() {
		    sync.acquire(1);
		    try {
			Thread.sleep(SMALL_DELAY_MS);
		    }
		    catch(Exception e) {
                        threadUnexpectedException();
                    }
		    sync.release(1);
		}
	    });
	try {
            t.start();
            Thread.sleep(SHORT_DELAY_MS);
            assertTrue(sync.isHeldExclusively());
            t.join();
            assertFalse(sync.isHeldExclusively());
        } catch(Exception e){
            unexpectedException();
        }
    }


    /**
     * acquireInterruptibly is interruptible.
     */
    public void testAcquireInterruptibly1() { 
	final Mutex sync = new Mutex();
	sync.acquire(1);
	Thread t = new Thread(new InterruptedSyncRunnable(sync));
        try {
            t.start();
            Thread.sleep(SHORT_DELAY_MS);
            t.interrupt();
            Thread.sleep(SHORT_DELAY_MS);
            sync.release(1);
            t.join();
        } catch(Exception e){
            unexpectedException();
        }
    } 

    /**
     * acquireInterruptibly succeeds when released, else is interruptible
     */
    public void testAcquireInterruptibly2() {
	final Mutex sync = new Mutex();	
	try {
            sync.acquireInterruptibly(1);
        } catch(Exception e) {
            unexpectedException();
        }
	Thread t = new Thread(new InterruptedSyncRunnable(sync));
        try {
            t.start();
            t.interrupt();
            assertTrue(sync.isHeldExclusively());
            t.join();
        } catch(Exception e){
            unexpectedException();
        }
    }

    /**
     * owns is true for a condition created by sync else false
     */
    public void testOwns() {
	final Mutex sync = new Mutex();	
        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
        final Mutex sync2 = new Mutex();
        assertTrue(sync.owns(c));
        assertFalse(sync2.owns(c));
    }

    /**
     * Calling await without holding sync throws IllegalMonitorStateException
     */
    public void testAwait_IllegalMonitor() {
	final Mutex sync = new Mutex();	
        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
        try {
            c.await();
            shouldThrow();
        }
        catch (IllegalMonitorStateException success) {
        }
        catch (Exception ex) {
            unexpectedException();
        }
    }

    /**
     * Calling signal without holding sync throws IllegalMonitorStateException
     */
    public void testSignal_IllegalMonitor() {
	final Mutex sync = new Mutex();	
        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
        try {
            c.signal();
            shouldThrow();
        }
        catch (IllegalMonitorStateException success) {
        }
        catch (Exception ex) {
            unexpectedException();
        }
    }

    /**
     * awaitNanos without a signal times out
     */
    public void testAwaitNanos_Timeout() {
	final Mutex sync = new Mutex();	
        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
        try {
            sync.acquire(1);
            long t = c.awaitNanos(100);
            assertTrue(t <= 0);
            sync.release(1);
        }
        catch (Exception ex) {
            unexpectedException();
        }
    }

    /**
     *  Timed await without a signal times out
     */
    public void testAwait_Timeout() {
	final Mutex sync = new Mutex();	
        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
        try {
            sync.acquire(1);
            assertFalse(c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
            sync.release(1);
        }
        catch (Exception ex) {
            unexpectedException();
        }
    }

    /**
     * awaitUntil without a signal times out
     */
    public void testAwaitUntil_Timeout() {
	final Mutex sync = new Mutex();	
        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
        try {
            sync.acquire(1);
            java.util.Date d = new java.util.Date();
            assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
            sync.release(1);
        }
        catch (Exception ex) {
            unexpectedException();
        }
    }

    /**
     * await returns when signalled
     */
    public void testAwait() {
	final Mutex sync = new Mutex();	
        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
	Thread t = new Thread(new Runnable() { 
		public void run() {
		    try {
			sync.acquire(1);
                        c.await();
                        sync.release(1);
		    }
		    catch(InterruptedException e) {
                        threadUnexpectedException();
                    }
		}
	    });

        try {
            t.start();
            Thread.sleep(SHORT_DELAY_MS);
            sync.acquire(1);
            c.signal();
            sync.release(1);
            t.join(SHORT_DELAY_MS);
            assertFalse(t.isAlive());
        }
        catch (Exception ex) {
            unexpectedException();
        }
    }



    /**
     * hasWaiters throws NPE if null
     */
    public void testHasWaitersNPE() {
	final Mutex sync = new Mutex();
        try {
            sync.hasWaiters(null);
            shouldThrow();
        } catch (NullPointerException success) {
        } catch (Exception ex) {
            unexpectedException();
        }
    }

    /**
     * getWaitQueueLength throws NPE if null
     */
    public void testGetWaitQueueLengthNPE() {
	final Mutex sync = new Mutex();
        try {
            sync.getWaitQueueLength(null);
            shouldThrow();
        } catch (NullPointerException success) {
        } catch (Exception ex) {
            unexpectedException();
        }
    }


    /**
     * getWaitingThreads throws NPE if null
     */
    public void testGetWaitingThreadsNPE() {
	final Mutex sync = new Mutex();
        try {
            sync.getWaitingThreads(null);
            shouldThrow();
        } catch (NullPointerException success) {
        } catch (Exception ex) {
            unexpectedException();
        }
    }


    /**
     * hasWaiters throws IAE if not owned
     */
    public void testHasWaitersIAE() {
	final Mutex sync = new Mutex();
        final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
	final Mutex sync2 = new Mutex();
        try {
            sync2.hasWaiters(c);
            shouldThrow();
        } catch (IllegalArgumentException success) {
        } catch (Exception ex) {
            unexpectedException();
        }
    }

    /**
     * hasWaiters throws IMSE if not synced
     */
    public void testHasWaitersIMSE() {
	final Mutex sync = new Mutex();
        final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
        try {
            sync.hasWaiters(c);
            shouldThrow();
        } catch (IllegalMonitorStateException success) {
        } catch (Exception ex) {
            unexpectedException();
        }
    }


    /**
     * getWaitQueueLength throws IAE if not owned
     */
    public void testGetWaitQueueLengthIAE() {
	final Mutex sync = new Mutex();
        final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
	final Mutex sync2 = new Mutex();
        try {
            sync2.getWaitQueueLength(c);
            shouldThrow();
        } catch (IllegalArgumentException success) {
        } catch (Exception ex) {
            unexpectedException();
        }
    }

    /**
     * getWaitQueueLength throws IMSE if not synced
     */
    public void testGetWaitQueueLengthIMSE() {
	final Mutex sync = new Mutex();
        final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
        try {
            sync.getWaitQueueLength(c);
            shouldThrow();
        } catch (IllegalMonitorStateException success) {
        } catch (Exception ex) {
            unexpectedException();
        }
    }


    /**
     * getWaitingThreads throws IAE if not owned
     */
    public void testGetWaitingThreadsIAE() {
	final Mutex sync = new Mutex();	
        final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
	final Mutex sync2 = new Mutex();	
        try {
            sync2.getWaitingThreads(c);
            shouldThrow();
        } catch (IllegalArgumentException success) {
        } catch (Exception ex) {
            unexpectedException();
        }
    }

    /**
     * getWaitingThreads throws IMSE if not synced
     */
    public void testGetWaitingThreadsIMSE() {
	final Mutex sync = new Mutex();	
        final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
        try {
            sync.getWaitingThreads(c);
            shouldThrow();
        } catch (IllegalMonitorStateException success) {
        } catch (Exception ex) {
            unexpectedException();
        }
    }



    /**
     * hasWaiters returns true when a thread is waiting, else false
     */
    public void testHasWaiters() {
	final Mutex sync = new Mutex();	
        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
	Thread t = new Thread(new Runnable() { 
		public void run() {
		    try {
			sync.acquire(1);
                        threadAssertFalse(sync.hasWaiters(c));
                        threadAssertEquals(0, sync.getWaitQueueLength(c));
                        c.await();
                        sync.release(1);
		    }
		    catch(InterruptedException e) {
                        threadUnexpectedException();
                    }
		}
	    });

        try {
            t.start();
            Thread.sleep(SHORT_DELAY_MS);
            sync.acquire(1);
            assertTrue(sync.hasWaiters(c));
            assertEquals(1, sync.getWaitQueueLength(c));
            c.signal();
            sync.release(1);
            Thread.sleep(SHORT_DELAY_MS);
            sync.acquire(1);
            assertFalse(sync.hasWaiters(c));
            assertEquals(0, sync.getWaitQueueLength(c));
            sync.release(1);
            t.join(SHORT_DELAY_MS);
            assertFalse(t.isAlive());
        }
        catch (Exception ex) {
            unexpectedException();
        }
    }

    /**
     * getWaitQueueLength returns number of waiting threads
     */
    public void testGetWaitQueueLength() {
	final Mutex sync = new Mutex();	
        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
	Thread t1 = new Thread(new Runnable() { 
		public void run() {
		    try {
			sync.acquire(1);
                        threadAssertFalse(sync.hasWaiters(c));
                        threadAssertEquals(0, sync.getWaitQueueLength(c));
                        c.await();
                        sync.release(1);
		    }
		    catch(InterruptedException e) {
                        threadUnexpectedException();
                    }
		}
	    });

	Thread t2 = new Thread(new Runnable() { 
		public void run() {
		    try {
			sync.acquire(1);
                        threadAssertTrue(sync.hasWaiters(c));
                        threadAssertEquals(1, sync.getWaitQueueLength(c));
                        c.await();
                        sync.release(1);
		    }
		    catch(InterruptedException e) {
                        threadUnexpectedException();
                    }
		}
	    });

        try {
            t1.start();
            Thread.sleep(SHORT_DELAY_MS);
            t2.start();
            Thread.sleep(SHORT_DELAY_MS);
            sync.acquire(1);
            assertTrue(sync.hasWaiters(c));
            assertEquals(2, sync.getWaitQueueLength(c));
            c.signalAll();
            sync.release(1);
            Thread.sleep(SHORT_DELAY_MS);
            sync.acquire(1);
            assertFalse(sync.hasWaiters(c));
            assertEquals(0, sync.getWaitQueueLength(c));
            sync.release(1);
            t1.join(SHORT_DELAY_MS);
            t2.join(SHORT_DELAY_MS);
            assertFalse(t1.isAlive());
            assertFalse(t2.isAlive());
        }
        catch (Exception ex) {
            unexpectedException();
        }
    }

    /**
     * getWaitingThreads returns only and all waiting threads
     */
    public void testGetWaitingThreads() {
	final Mutex sync = new Mutex();	
        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
	Thread t1 = new Thread(new Runnable() { 
		public void run() {
		    try {
			sync.acquire(1);
                        threadAssertTrue(sync.getWaitingThreads(c).isEmpty());
                        c.await();
                        sync.release(1);
		    }
		    catch(InterruptedException e) {
                        threadUnexpectedException();
                    }
		}
	    });

	Thread t2 = new Thread(new Runnable() { 
		public void run() {
		    try {
			sync.acquire(1);
                        threadAssertFalse(sync.getWaitingThreads(c).isEmpty());
                        c.await();
                        sync.release(1);
		    }
		    catch(InterruptedException e) {
                        threadUnexpectedException();
                    }
		}
	    });

        try {
            sync.acquire(1);
            assertTrue(sync.getWaitingThreads(c).isEmpty());
            sync.release(1);
            t1.start();
            Thread.sleep(SHORT_DELAY_MS);
            t2.start();
            Thread.sleep(SHORT_DELAY_MS);
            sync.acquire(1);
            assertTrue(sync.hasWaiters(c));
            assertTrue(sync.getWaitingThreads(c).contains(t1));
            assertTrue(sync.getWaitingThreads(c).contains(t2));
            c.signalAll();
            sync.release(1);
            Thread.sleep(SHORT_DELAY_MS);
            sync.acquire(1);
            assertFalse(sync.hasWaiters(c));
            assertTrue(sync.getWaitingThreads(c).isEmpty());
            sync.release(1);
            t1.join(SHORT_DELAY_MS);
            t2.join(SHORT_DELAY_MS);
            assertFalse(t1.isAlive());
            assertFalse(t2.isAlive());
        }
        catch (Exception ex) {
            unexpectedException();
        }
    }



    /**
     * awaitUninterruptibly doesn't abort on interrupt
     */
    public void testAwaitUninterruptibly() {
	final Mutex sync = new Mutex();	
        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
	Thread t = new Thread(new Runnable() { 
		public void run() {
                    sync.acquire(1);
                    c.awaitUninterruptibly();
                    sync.release(1);
		}
	    });

        try {
            t.start();
            Thread.sleep(SHORT_DELAY_MS);
            t.interrupt();
            sync.acquire(1);
            c.signal();
            sync.release(1);
            t.join(SHORT_DELAY_MS);
            assertFalse(t.isAlive());
        }
        catch (Exception ex) {
            unexpectedException();
        }
    }

    /**
     * await is interruptible
     */
    public void testAwait_Interrupt() {
	final Mutex sync = new Mutex();	
        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
	Thread t = new Thread(new Runnable() { 
		public void run() {
		    try {
			sync.acquire(1);
                        c.await();
                        sync.release(1);
                        threadShouldThrow();
		    }
		    catch(InterruptedException success) {
                    }
		}
	    });

        try {
            t.start();
            Thread.sleep(SHORT_DELAY_MS);
            t.interrupt();
            t.join(SHORT_DELAY_MS);
            assertFalse(t.isAlive());
        }
        catch (Exception ex) {
            unexpectedException();
        }
    }

    /**
     * awaitNanos is interruptible
     */
    public void testAwaitNanos_Interrupt() {
	final Mutex sync = new Mutex();	
        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
	Thread t = new Thread(new Runnable() { 
		public void run() {
		    try {
			sync.acquire(1);
                        c.awaitNanos(1000 * 1000 * 1000); // 1 sec
                        sync.release(1);
                        threadShouldThrow();
		    }
		    catch(InterruptedException success) {
                    }
		}
	    });

        try {
            t.start();
            Thread.sleep(SHORT_DELAY_MS);
            t.interrupt();
            t.join(SHORT_DELAY_MS);
            assertFalse(t.isAlive());
        }
        catch (Exception ex) {
            unexpectedException();
        }
    }

    /**
     * awaitUntil is interruptible
     */
    public void testAwaitUntil_Interrupt() {
	final Mutex sync = new Mutex();	
        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
	Thread t = new Thread(new Runnable() { 
		public void run() {
		    try {
			sync.acquire(1);
                        java.util.Date d = new java.util.Date();
                        c.awaitUntil(new java.util.Date(d.getTime() + 10000));
                        sync.release(1);
                        threadShouldThrow();
		    }
		    catch(InterruptedException success) {
                    }
		}
	    });

        try {
            t.start();
            Thread.sleep(SHORT_DELAY_MS);
            t.interrupt();
            t.join(SHORT_DELAY_MS);
            assertFalse(t.isAlive());
        }
        catch (Exception ex) {
            unexpectedException();
        }
    }

    /**
     * signalAll wakes up all threads
     */
    public void testSignalAll() {
	final Mutex sync = new Mutex();	
        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
	Thread t1 = new Thread(new Runnable() { 
		public void run() {
		    try {
			sync.acquire(1);
                        c.await();
                        sync.release(1);
		    }
		    catch(InterruptedException e) {
                        threadUnexpectedException();
                    }
		}
	    });

	Thread t2 = new Thread(new Runnable() { 
		public void run() {
		    try {
			sync.acquire(1);
                        c.await();
                        sync.release(1);
		    }
		    catch(InterruptedException e) {
                        threadUnexpectedException();
                    }
		}
	    });

        try {
            t1.start();
            t2.start();
            Thread.sleep(SHORT_DELAY_MS);
            sync.acquire(1);
            c.signalAll();
            sync.release(1);
            t1.join(SHORT_DELAY_MS);
            t2.join(SHORT_DELAY_MS);
            assertFalse(t1.isAlive());
            assertFalse(t2.isAlive());
        }
        catch (Exception ex) {
            unexpectedException();
        }
    }


    /**
     * toString indicates current state
     */
    public void testToString() {
        Mutex sync = new Mutex();
        String us = sync.toString();
        assertTrue(us.indexOf("State = 0") >= 0);
        sync.acquire(1);
        String ls = sync.toString();
        assertTrue(ls.indexOf("State = 1") >= 0);
    }

    /**
     * A serialized AQS deserializes with current state
     */
    public void testSerialization() {
        Mutex l = new Mutex();
        l.acquire(1);
        assertTrue(l.isHeldExclusively());

        try {
            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
            out.writeObject(l);
            out.close();

            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
            Mutex r = (Mutex) in.readObject();
            assertTrue(r.isHeldExclusively());
        } catch(Exception e){
            e.printStackTrace();
            unexpectedException();
        }
    }


    /**
     * tryReleaseShared setting state changes getState
     */
    public void testGetStateWithReleaseShared() {
	final BooleanLatch l = new BooleanLatch();
	assertFalse(l.isSignalled());
	l.releaseShared(0);
	assertTrue(l.isSignalled());
    }

    /**
     * releaseShared has no effect when already signalled
     */
    public void testReleaseShared() {
	final BooleanLatch l = new BooleanLatch();
	assertFalse(l.isSignalled());
	l.releaseShared(0);
	assertTrue(l.isSignalled());
	l.releaseShared(0);
	assertTrue(l.isSignalled());
    }

    /**
     * acquireSharedInterruptibly returns after release, but not before
     */
    public void testAcquireSharedInterruptibly() {
	final BooleanLatch l = new BooleanLatch();

	Thread t = new Thread(new Runnable() {
		public void run() {
		    try {
                        threadAssertFalse(l.isSignalled());
			l.acquireSharedInterruptibly(0);
                        threadAssertTrue(l.isSignalled());
		    } catch(InterruptedException e){
                        threadUnexpectedException();
                    }
		}
	    });
	try {
            t.start();
            assertFalse(l.isSignalled());
            Thread.sleep(SHORT_DELAY_MS);
            l.releaseShared(0);
            assertTrue(l.isSignalled());
            t.join();
        } catch (InterruptedException e){
            unexpectedException();
        }
    }
    

    /**
     * acquireSharedTimed returns after release
     */
    public void testAsquireSharedTimed() {
	final BooleanLatch l = new BooleanLatch();

	Thread t = new Thread(new Runnable() {
		public void run() {
		    try {
                        threadAssertFalse(l.isSignalled());
			threadAssertTrue(l.tryAcquireSharedNanos(0, MEDIUM_DELAY_MS* 1000 * 1000));
                        threadAssertTrue(l.isSignalled());

		    } catch(InterruptedException e){
                        threadUnexpectedException();
                    }
		}
	    });
	try {
            t.start();
            assertFalse(l.isSignalled());
            Thread.sleep(SHORT_DELAY_MS);
            l.releaseShared(0);
            assertTrue(l.isSignalled());
            t.join();
        } catch (InterruptedException e){
            unexpectedException();
        }
    }
    
    /**
     * acquireSharedInterruptibly throws IE if interrupted before released
     */
    public void testAcquireSharedInterruptibly_InterruptedException() {
        final BooleanLatch l = new BooleanLatch();
        Thread t = new Thread(new Runnable() {
                public void run() {
                    try {
                        threadAssertFalse(l.isSignalled());
                        l.acquireSharedInterruptibly(0);
                        threadShouldThrow();
                    } catch(InterruptedException success){}
                }
            });
	t.start();
	try {
            assertFalse(l.isSignalled());
            t.interrupt();
            t.join();
        } catch (InterruptedException e){
            unexpectedException();
        }
    }

    /**
     * acquireSharedTimed throws IE if interrupted before released
     */
    public void testAcquireSharedNanos_InterruptedException() {
        final BooleanLatch l = new BooleanLatch();
        Thread t = new Thread(new Runnable() {
                public void run() {
                    try {
                        threadAssertFalse(l.isSignalled());
                        l.tryAcquireSharedNanos(0, SMALL_DELAY_MS* 1000 * 1000);
                        threadShouldThrow();                        
                    } catch(InterruptedException success){}
                }
            });
        t.start();
        try {
            Thread.sleep(SHORT_DELAY_MS);
            assertFalse(l.isSignalled());
            t.interrupt();
            t.join();
        } catch (InterruptedException e){
            unexpectedException();
        }
    }

    /**
     * acquireSharedTimed times out if not released before timeout
     */
    public void testAcquireSharedNanos_Timeout() {
        final BooleanLatch l = new BooleanLatch();
        Thread t = new Thread(new Runnable() {
                public void run() {
                    try {
                        threadAssertFalse(l.isSignalled());
                        threadAssertFalse(l.tryAcquireSharedNanos(0, SMALL_DELAY_MS* 1000 * 1000));
                    } catch(InterruptedException ie){
                        threadUnexpectedException();
                    }
                }
            });
        t.start();
        try {
            Thread.sleep(SHORT_DELAY_MS);
            assertFalse(l.isSignalled());
            t.join();
        } catch (InterruptedException e){
            unexpectedException();
        }
    }

    
}
