// Concurrent Programming - CS 498-598
// Summer 2002 - A simple, one-slot buffer.


// A simple one-slot buffer with member functions put() and get().  The
// Interrupted Exception should be handled more sensibly than it is here.


class 
OneSlotBuffer {

  private Object buffer;
  private boolean buffer_full = false;


  public synchronized Object
  get() {
    
    while (!buffer_full)
      try { wait(); }
      catch (InterruptedException ie) { }

    Object o = buffer;
    buffer = null;
    buffer_full = false;

    notify();

    return o;
    }


  public synchronized void 
  put(Object o) {

    while (buffer_full) 
      try { wait(); }
      catch (InterruptedException ie) { }

    assert buffer == null;
    buffer = o;
    buffer_full = true;

    notify();
    }
  }


// A class that transforms some numbers and prints them.  This class shows
// how to pass arguments into a Runnable: via the constructor and private 
// variables.


class 
Writer 
implements Runnable {

  OneSlotBuffer toCalculator, fromCalculator;
  
  public void run() {
    for (int i = 0; i < 10; i++) {
      toCalculator.put(new Integer(i));
      Integer ans = (Integer) fromCalculator.get();
      System.out.println(i + " gets turned into " + ans.intValue());
      }
    toCalculator.put(null);
    }

  Writer(OneSlotBuffer inbound, OneSlotBuffer outbound) {
    toCalculator = outbound;
    fromCalculator = inbound;
    }
}


// A class that accepts a number and transforms it somehow.


class 
Calculator
implements Runnable {

  OneSlotBuffer toClient, fromClient;
  
  public void run() {
    while (true) {
      Object o = fromClient.get();
      if (null == o) break;
      final int i = ((Integer) o).intValue();
      toClient.put(new Integer(i*i));
      }
    }

  Calculator(OneSlotBuffer inbound, OneSlotBuffer outbound) {
    toClient = outbound;
    fromClient = inbound;
    }
}


// Put them all together and go.


class
OneSlotBufferExample {

  public static void
  main(String args[]) {
    OneSlotBuffer 
      w2c = new OneSlotBuffer(),
      c2w = new OneSlotBuffer();

    new Thread(new Writer(c2w, w2c)).start();
    new Thread(new Calculator(w2c, c2w)).start();
    }
  
  }


// $Log: OneSlotBufferExample.java,v $
// Revision 1.2  2002/07/11 17:05:35  rclayton
// Delete "assert buffer != null" from OneSlotBuffer.get() because it's o.k.
// to pass null via a buffer.
//
// Revision 1.1  2002/07/11 16:53:40  rclayton
// Initial revision
//


syntax highlighted by Code2HTML, v. 0.9