/*****************************************************
 * jr generated file
 ****************************************************/
import java.rmi.*;
import java.util.LinkedList;
import java.util.List;
import edu.ucdavis.jr.*;
import edu.ucdavis.jr.jrx.*;
import java.rmi.*;
import java.io.Serializable;

public class InOp_voidTovoid_impl
  extends Op_impl
  implements InOp_voidTovoid
{
    protected List msg_list;
    protected List wait_list;
    protected InLock theLock;
    public InOp_voidTovoid_impl() throws java.rmi.RemoteException
    {
	this(true, true);
    }
    public static InOp_voidTovoid_impl create()
    {
	try {
	return new InOp_voidTovoid_impl();
	} catch (RemoteException e) { throw new edu.ucdavis.jr.jrCommunicationException(e); }
    }
    public InOp_voidTovoid_impl(int initializer) throws java.rmi.RemoteException
    {
	this();
	if (initializer < 0) throw new jrRuntimeError("op initialized with a negative value");
	for (int i = 0; i < initializer; i++)
	    send(jrvm.getTimestamp(), null, null, null);
    }
    public static InOp_voidTovoid_impl create(int initializer)
    {
	try {
	return new InOp_voidTovoid_impl(initializer);
	} catch (RemoteException e) { throw new edu.ucdavis.jr.jrCommunicationException(e); }
    }
    public InOp_voidTovoid_impl(boolean reg) throws java.rmi.RemoteException
    {
	this(reg, true);
    }
    public InOp_voidTovoid_impl(boolean reg, boolean queue) throws java.rmi.RemoteException
    {
	super(reg);
	if (queue)
	{
	    msg_list = new LinkedList();
	    wait_list = new LinkedList();
	}
theLock = new InLock_impl(jrvm.vmName, false);
    }
    public void call(long JRtimestamp) throws java.rmi.RemoteException

    {
	throw new jrRuntimeError("Call not allowed on this op!");
    }
    public Cap_voidTovoid cocall(long JRtimestamp) throws java.rmi.RemoteException

    {
	throw new jrRuntimeError("Call not allowed on this op!");
    }
    public Cap_voidTovoid cocall(long JRtimestamp, edu.ucdavis.jr.RemoteHandler handler, Cap_voidTovoid fretOp) throws java.rmi.RemoteException
    {
	throw new jrRuntimeError("Call not allowed on this op!");
    }
    public void send(long JRtimestamp) throws java.rmi.RemoteException
    {
	send(JRtimestamp, null, null, null);
    }
    public void send(long JRtimestamp, edu.ucdavis.jr.RemoteHandler handler) throws java.rmi.RemoteException
    {
	send(JRtimestamp, null, handler, null);
    }
    public void send(long JRtimestamp, Exception thrown) throws java.rmi.RemoteException
    {
	send(JRtimestamp, null, null, thrown);
    }
    public void send(long JRtimestamp, 	Op_voidTovoid.JRProxyOp retOp, 
edu.ucdavis.jr.RemoteHandler handler, Exception thrown) throws java.rmi.RemoteException
    {
	Recv_voidTovoid newmsg =
	    new Recv_voidTovoid(retOp, handler, thrown, jrvm.setTimestamp(JRtimestamp));
	synchronized (this)
	{
	  synchronized (this.wait_list)
	  {
	    this.wait_list.add(newmsg);
	  }
	}
	boolean lockp = this.theLock.lock_or_register(this);
	synchronized (this)
	{
	    if(lockp) // this inOp successfully locked the equiv. class
	    {
		synchronized (this.wait_list)
		{
		    synchronized (this.msg_list)
		    {
			while (this.wait_list.size() != 0)
			{
			    this.msg_list.add((Recv_voidTovoid)this.wait_list.remove(0));
			}
		    }
		}
	    }
	}
	if(lockp)
	{
	    // awaken a waiting process (pass the baton)
	    this.theLock.unlockMes();
	}
    }
    public void send(long JRtimestamp, 	Op_voidTovoid.JRProxyOp retOp, Cap_voidTovoid fretOp, 
edu.ucdavis.jr.RemoteHandler handler, Exception thrown) throws java.rmi.RemoteException
    {
	Recv_voidTovoid newmsg =
	    new Recv_voidTovoid(retOp, fretOp, handler, thrown, jrvm.setTimestamp(JRtimestamp));
	synchronized (this)
	{
	  synchronized (this.wait_list)
	  {
	    this.wait_list.add(newmsg);
	  }
	}
	boolean lockp = this.theLock.lock_or_register(this);
	synchronized (this)
	{
	    if(lockp) // this inOp successfully locked the equiv. class
	    {
		synchronized (this.wait_list)
		{
		    synchronized (this.msg_list)
		    {
			while (this.wait_list.size() != 0)
			{
			    this.msg_list.add((Recv_voidTovoid)this.wait_list.remove(0));
			}
		    }
		}
	    }
	}
	if(lockp)
	{
	    // awaken a waiting process (pass the baton)
	    this.theLock.unlockMes();
	}
    }
	public Cap_voidTovoid cosend(long JRtimestamp) throws java.rmi.RemoteException
    {
	return cosend(JRtimestamp, null, null, null);
    }
    public Cap_voidTovoid cosend(long JRtimestamp, edu.ucdavis.jr.RemoteHandler handler) throws java.rmi.RemoteException
    {
	return cosend(JRtimestamp, null, handler, null);
    }
    public Cap_voidTovoid cosend(long JRtimestamp, Exception thrown) throws java.rmi.RemoteException
    {
	return cosend(JRtimestamp, null, null, thrown);
    }
    public Cap_voidTovoid cosend(long JRtimestamp, 	Op_voidTovoid.JRProxyOp retOp, 
edu.ucdavis.jr.RemoteHandler handler, Exception thrown) throws java.rmi.RemoteException
    {
	Op_voidTovoid.JRProxyOp op = new Op_voidTovoid.JRProxyOp(new InOp_voidTovoid_impl());
op.send(JRtimestamp);
	Recv_voidTovoid newmsg =
	    new Recv_voidTovoid(retOp, handler, thrown, jrvm.setTimestamp(JRtimestamp));
	synchronized (this)
	{
	  synchronized (this.wait_list)
	  {
	    this.wait_list.add(newmsg);
	  }
	}
	boolean lockp = this.theLock.lock_or_register(this);
	synchronized (this)
	{
	    if(lockp) // this inOp successfully locked the equiv. class
	    {
		synchronized (this.wait_list)
		{
		    synchronized (this.msg_list)
		    {
			while (this.wait_list.size() != 0)
			{
			    this.msg_list.add((Recv_voidTovoid)this.wait_list.remove(0));
			}
		    }
		}
	    }
	}
	if(lockp)
	{
	    // awaken a waiting process (pass the baton)
	    this.theLock.unlockMes();
	}
	return new Cap_voidTovoid(op);
    }
    public Recv_voidTovoid recv() throws java.rmi.RemoteException
    {
	Recv_voidTovoid ret;
	boolean empty, exception = false;
	jrvm.ariseAndReceive(); // from caller
	try
	{
	    exception = true;
	    jrvm.sendAndDie(); // to lock
	    this.theLock.lock();
	    jrvm.ariseAndReceive(); // from lock
	    exception = false;

	    while (true)
	    {
		empty = false;
		synchronized (this.msg_list)
		{
		    if (this.msg_list.size() == 0)
			empty = true;
		}
		if (empty)
		{
		    exception = true;
		    jrvm.sendAndDie(); // to lock
		    this.theLock.waitOnLock();
		    jrvm.ariseAndReceive(); // from lock
		    exception = false;
		}
		else
		    break;
	    }
	    try
	    {
		ret = (Recv_voidTovoid)this.msg_list.remove(0);
	    }
	    catch (IndexOutOfBoundsException doh)
	    {
		exception = true;
		jrvm.sendAndDie(); // to lock
		this.theLock.unlock();
		jrvm.ariseAndReceive(); // from lock
		exception = false;
		throw new jrRuntimeError("Unexpected empty operation!");
	    }
	    catch (Exception doh)
	    {
		exception = true;
		jrvm.sendAndDie(); // to lock
		this.theLock.unlock();
		jrvm.ariseAndReceive(); // from lock
		exception = false;
		throw new jrRuntimeError("Exception while receiving from an operation!");
	    }
	    // release the lock
	    exception = true;
	    jrvm.sendAndDie(); // to lock
	    this.theLock.unlock();
	    jrvm.ariseAndReceive(); // from lock
	    exception = false;
	    if (ret == null)
		throw new jrRuntimeError("Null receive node!");
	    return ret;
	}
	finally
	{
	    if (!exception)
	    {
		jrvm.sendAndDie(); // to caller
	    }
	}
    }
    public synchronized void deliverPendingMessages()
	throws java.rmi.RemoteException
    {
	// the equiv class should already be locked
	try
	{
	  synchronized (this.wait_list)
	  {
	   synchronized (this.msg_list)
	   {
	    while (this.wait_list.size() != 0)
	    {
		this.msg_list.add((Recv_voidTovoid)this.wait_list.remove(0));
	    }
	   }
	  }
	}
	catch (IndexOutOfBoundsException doh)
	{
	    throw new jrRuntimeError("Unexpected empty operation!");
	}
	catch (Exception doh)
	{
	    throw new jrRuntimeError("Exception while sending to an operation!");
	}
    }
    public synchronized int length() throws java.rmi.RemoteException
    {
	int i;
	if (msg_list == null) return 0;
	return msg_list.size();
    }
    public synchronized InLock getLock() throws java.rmi.RemoteException
    {
	return this.theLock;
    }
    public synchronized long getFirstTime() throws java.rmi.RemoteException
    {
	if (this.msg_list.size() != 0)
	    return ((Recv_voidTovoid)this.msg_list.get(0)).timestamp;
	return -1;
    }
    public synchronized InOpIterator elements() throws java.rmi.RemoteException
    {
	return new InOpIterator_impl(new InOpIteratorRemote_impl(msg_list));
    }
    public boolean isRemote(String site) throws java.rmi.RemoteException
    {
	return (jrvm.thisVM.getName().compareTo(site) != 0);
    }
}
