/**
 * SyncChannel
 * 
 */

public class SyncChannel {
  /**
   * object storage
   */
  private Object buffer;

  /**
   * validity of the buffer
   */
  private boolean valid;

  /**
   * semaphore indicating an empty buffer
   */
  private Sema empty;

  /**
   * semaphore indicating a filled buffer
   */
  private Sema full;

  /**
   * mutex for send
   */
  private Object snd;

  /**
   * Constructs a synchrnous Channel
   */
  public SyncChannel() {
    buffer = new Object();
    valid = false;
    empty = new Sema(0);
    full = new Sema(0);
    snd = new Object();
  }

  /**
   * Sends an object to the channel
   */
  public void send(Object v) {
    synchronized (snd) {
      buffer = v;
      valid = true;
      full.V();
      empty.P();
    }
  }

  /**
   * Receives an object from the channel
   */
  public Object receive() {
    Object v = null;
    full.P();
    v = buffer;
    valid = false;
    empty.V();
    return v;
  }
}
