package JThread.examples.crew;

import JThread.stream.*;

public class CrewedString implements java.io.Serializable
{
    public CrewedString( String myString )
    {
        this.myString = myString;
    }
    
    public String read( String reader ) throws InvalidUnlock, ShutdownException
    {
        String result;
        Lock capability = myCrew.readLock();
        System.out.println( "  " + reader + " starts read" );
        result = myString;
        
        try {
            Thread.currentThread().sleep( (int)(Math.random()*500.0) );
        } catch ( InterruptedException e ) {
            System.out.println( e.toString() );
        }
        reads++;
        System.out.println( "  " + reader + " ends read of " + result );
        myCrew.unlock( capability );
        
        // shouldn't be able to unlock again
        try {
            myCrew.unlock( capability );
        } catch ( InvalidUnlock ul ) {
            // good work!
            return result;
        }
        System.out.println( "!!! Imposter read unlock! !!!" );
        return null;
    }
    
    public void write( String writer, String str ) throws InvalidUnlock, ShutdownException
    {
        Lock capability = myCrew.writeLock();
        System.out.println( writer + " starts write of " + str + 
            "; old value " + myString + " had " + reads + " reads" );
        myString = "!!! Inconsistent value !!!";
        
        try {
            Thread.currentThread().sleep( (int)(Math.random()*500.0) );
        } catch ( InterruptedException e ) {
            System.out.println( e.toString() );
        }
        myString = str;
        reads = 0;
        System.out.println( writer + " ends write of " + str );
        myCrew.unlock( capability );
        
        // shouldn't be able to unlock again
        try {
            myCrew.unlock( capability );
        } catch ( InvalidUnlock ul ) {
            // good work!
            return;
        }
        System.out.println( "!!! Imposter write unlock! !!!" );
    }
    
    private String myString;
    private Crewable myCrew = new Crew();
    private int reads = 0;
    private Lock oldCapability = null;
}