//@author: j.n.magee 11/11/96

import java.awt.*;
import java.applet.*;

/********************************************************/

class Reader implements Runnable {

    ReadWrite lock_;

    Reader(ReadWrite lock) {
        lock_ = lock;
    }

    public void run() {
        int i=0;
        while(true)  {
            int s=DisplayThread.getSplit();
            for(;i < (60-s)/2;++i) DisplayThread.rotate();
            // begin critical section
            lock_.acquireRead();
            DisplayThread.mark();
            for(;i < 30+s/2;++i) DisplayThread.rotate();
            DisplayThread.unmark();
            lock_.releaseRead();
            for(;i < 60;++i)DisplayThread.rotate();
            i = 0;
        }
    }
}

/********************************************************/

class Writer implements Runnable {

    ReadWrite lock_;

    Writer(ReadWrite lock) {
        lock_ = lock;
    }

    public void run() {
        int i=0;
        while(true)  {
            int s=DisplayThread.getSplit();
            for(;i < (60-s)/2;++i) DisplayThread.rotate();
            // begin critical section
            lock_.acquireWrite();
            DisplayThread.mark();
            for(;i < 30 + s/2;++i) DisplayThread.rotate();
            DisplayThread.unmark();
            lock_.releaseWrite();
            for(;i < 60;++i)DisplayThread.rotate();
            i = 0;
        }
    }
}

/********************************************************/

public class ReadWriteLock extends Applet {

    ThreadPanel read1_;
    ThreadPanel read2_;
    ThreadPanel write1_;
    ThreadPanel write2_;

    public void init() {
        String rwClass = getParameter("rwClass");
        setLayout(new BorderLayout());
        TextCanvas t = new TextCanvas(rwClass + " Lock");
        DisplayReadWrite lock;
        if (rwClass.equals("ReadWriteVs1"))
           lock = new DisplayReadWrite(t,new ReadWriteVs1());
        else if (rwClass.equals("ReadWriteVs2"))
           lock = new DisplayReadWrite(t,new ReadWriteVs2());
        else if (rwClass.equals("ReadWriteVs3"))
           lock = new DisplayReadWrite(t,new ReadWriteVs3());
        else
        lock = new DisplayReadWrite(t,new ReadWriteVs1());
        add("Center",t);
        Panel p = new Panel();
        p.add(read1_=new ThreadPanel("Reader 1",Color.blue,new Reader(lock)));
        p.add(read2_=new ThreadPanel("Reader 2",Color.blue,new Reader(lock)));
        p.add(write1_=new ThreadPanel("Writer 1",Color.yellow,new Writer(lock)));
        p.add(write2_=new ThreadPanel("Writer 2",Color.yellow,new Writer(lock)));
        add("South",p);
    }

    public void start() {
        super.start();
    }

    public void stop() {
        read1_.passivate();
        read2_.passivate();
        write1_.passivate();
        write2_.passivate();
     }

   public void destroy() {
        read1_.stop();
        read2_.stop();
        write1_.stop();
        write2_.stop();
   }

}

