ptolemy.domains.csp.kernel
Class CSPReceiver

java.lang.Object
  extended by ptolemy.actor.AbstractReceiver
      extended by ptolemy.domains.csp.kernel.CSPReceiver
All Implemented Interfaces:
ProcessReceiver, Receiver

public class CSPReceiver
extends AbstractReceiver
implements ProcessReceiver

Receiver for CSP style communication. In CSP all communication is via synchronous message passing, so both the the sending and receiving process need to rendezvous at the receiver. For rendezvous, the receiver is the key synchronization point. It is assumed each receiver has at most one thread trying to send to it and at most one thread trying to receive from it at any one time. The receiver performs the synchronization necessary for simple rendezvous (get() and put() operations). It also stores the flags that allow the ConditionalSend and ConditionalReceive branches to know when they can proceed.

Since:
Ptolemy II 0.2
Version:
$Id: CSPReceiver.java 57040 2010-01-27 20:52:32Z cxh $
Author:
Neil Smyth, John S. Davis II, Edward A. Lee
Accepted Rating:
Green (kienhuis)
Proposed Rating:
Red (nsmyth)

Field Summary
private  BoundaryDetector _boundaryDetector
           
private  java.lang.Thread _conditionalReceiveWaiting
          Flag indicating whether or not a conditional receive is waiting to rendezvous.
private  java.lang.Thread _conditionalSendWaiting
          Flag indicating whether or not a conditional send is waiting to rendezvous.
private  IllegalActionException _exception
          Exception that might be set in putToAll().
private  java.lang.Thread _getWaiting
          Thread blocked on a get(), if any.
private  boolean _modelFinished
          Flag indicating that any subsequent attempts to rendezvous at this receiver should cause the attempting processes to terminate.
private  AbstractBranchController _otherController
          obsolete when implement containment
private  int _otherID
           
private  java.lang.Thread _putWaiting
          Thread waiting on a put(), if any.
private  boolean _rendezvousComplete
          Flag indicating whether state of rendezvous.
private  TerminateProcessException _terminateException
          Exception that might be set in putToAll().
private  int _threadCount
          Thread count used in putToAll().
private  Token _token
          The token being transferred during the rendezvous.
 
Constructor Summary
CSPReceiver()
          Construct a CSPReceiver with no container.
CSPReceiver(IOPort container)
          Construct a CSPReceiver with the specified container.
 
Method Summary
private  void _checkFlags()
          Check the flags controlling the state of the receiver and hence the actor process trying to rendezvous with it.
protected  void _checkFlagsAndWait()
          This method wraps the wait() call between checks on the state of the receiver.
protected  CSPDirector _getDirector()
          Return the director that is controlling the execution of this model.
protected  AbstractBranchController _getOtherController()
          Return the controller of the conditional branch to reach the rendezvous point first.
protected  int _getOtherID()
          Return the branch ID of the branch that requested the conditional receive.
protected  boolean _isConditionalReceiveWaiting()
          Return whether a ConditionalReceive is trying to rendezvous with this receiver.
protected  boolean _isConditionalSendWaiting()
          Return whether a ConditionalSend is trying to rendezvous with this receiver.
protected  boolean _isGetWaiting()
          Return whether a get() is waiting to rendezvous at this receiver.
protected  boolean _isPutWaiting()
          Flag indicating whether or not a put() is waiting to rendezvous at this receiver.
protected  void _setConditionalReceive(boolean ready, AbstractBranchController controller, int otherID)
          Set a flag so that a ConditionalSend branch knows whether or not a ConditionalReceive is ready to rendezvous with it.
protected  void _setConditionalSend(boolean ready, AbstractBranchController controller, int otherID)
          Set a flag so that a ConditionalReceive branch knows whether or not a ConditionalSend is ready to rendezvous with it.
 void clear()
          Reset local flags.
 Token get()
          Get a token from this receiver.
 boolean hasRoom()
          Return true.
 boolean hasRoom(int tokens)
          Return true.
 boolean hasToken()
          Return true.
 boolean hasToken(int tokens)
          Return true.
 boolean isConnectedToBoundary()
          Return true if this receiver is connected to the inside of a boundary port.
 boolean isConnectedToBoundaryInside()
          Return true if this receiver is connected to the inside of a boundary port.
 boolean isConnectedToBoundaryOutside()
          Return true if this receiver is connected to the outside of a boundary port.
 boolean isConsumerReceiver()
          This class serves as an example of a ConsumerReceiver and hence this method returns true.
 boolean isInsideBoundary()
          Return true if this receiver is contained on the inside of a boundary port.
 boolean isOutsideBoundary()
          Return true if this receiver is contained on the outside of a boundary port.
 boolean isProducerReceiver()
          Return true if this receiver is on an outside or an inside boundary.
 boolean isReadBlocked()
          Return true if there is a get or a conditional receive waiting on this receiver.
 boolean isWriteBlocked()
          Return true if there is either a put or a conditional send waiting on this receiver.
 void put(Token token)
          Put a token into the mailbox receiver.
 void putArrayToAll(Token[] tokens, int numberOfTokens, Receiver[] receivers)
          Put a sequence of tokens to all receivers in the specified array.
 void putToAll(Token token, Receiver[] receivers)
          Put to all receivers in the specified array.
 void requestFinish()
          The model has finished executing, so set a flag so that the next time an actor tries to get or put it gets a TerminateProcessException which will cause it to finish.
 void reset()
          Reset local flags.
 
Methods inherited from class ptolemy.actor.AbstractReceiver
elementList, getArray, getContainer, getCurrentTime, getModelTime, isKnown, putArray, setContainer, toString
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface ptolemy.actor.Receiver
elementList, getArray, getContainer, isKnown, putArray, setContainer
 

Field Detail

_boundaryDetector

private BoundaryDetector _boundaryDetector

_conditionalReceiveWaiting

private java.lang.Thread _conditionalReceiveWaiting
Flag indicating whether or not a conditional receive is waiting to rendezvous.


_conditionalSendWaiting

private java.lang.Thread _conditionalSendWaiting
Flag indicating whether or not a conditional send is waiting to rendezvous.


_exception

private IllegalActionException _exception
Exception that might be set in putToAll().


_getWaiting

private java.lang.Thread _getWaiting
Thread blocked on a get(), if any.


_modelFinished

private boolean _modelFinished
Flag indicating that any subsequent attempts to rendezvous at this receiver should cause the attempting processes to terminate.


_otherController

private AbstractBranchController _otherController
obsolete when implement containment


_otherID

private int _otherID

_putWaiting

private java.lang.Thread _putWaiting
Thread waiting on a put(), if any.


_rendezvousComplete

private boolean _rendezvousComplete
Flag indicating whether state of rendezvous.


_terminateException

private TerminateProcessException _terminateException
Exception that might be set in putToAll().


_threadCount

private int _threadCount
Thread count used in putToAll().


_token

private Token _token
The token being transferred during the rendezvous.

Constructor Detail

CSPReceiver

public CSPReceiver()
Construct a CSPReceiver with no container.


CSPReceiver

public CSPReceiver(IOPort container)
            throws IllegalActionException
Construct a CSPReceiver with the specified container.

Parameters:
container - The port containing this receiver.
Throws:
IllegalActionException - If this receiver cannot be contained by the proposed container.
Method Detail

clear

public void clear()
Reset local flags.

Specified by:
clear in interface Receiver
Overrides:
clear in class AbstractReceiver

get

public Token get()
          throws TerminateProcessException
Get a token from this receiver. This method does not return until the rendezvous has been completed. This method is internally synchronized on the director.

Specified by:
get in interface Receiver
Specified by:
get in class AbstractReceiver
Returns:
The token contained by this receiver.
Throws:
TerminateProcessException - If the actor to which this receiver belongs has been terminated while still running i.e it was not allowed to run to completion.

hasRoom

public boolean hasRoom()
Return true. This method returns true in all cases to indicate that the next call to put() will succeed without throwing a NoRoomException, as indeed it will, even if not right away. Note that if this were to return true only if a rendezvous was pending, then polymorphic actors would busy wait.

Specified by:
hasRoom in interface Receiver
Specified by:
hasRoom in class AbstractReceiver
Returns:
True.

hasRoom

public boolean hasRoom(int tokens)
Return true. This method returns true in all cases to indicate that any number of calls to put() will succeed without throwing a NoRoomException, as indeed they will, even if not right away. Note that if this were to return true only if a rendezvous was pending, then polymorphic actors would busy wait.

Specified by:
hasRoom in interface Receiver
Specified by:
hasRoom in class AbstractReceiver
Parameters:
tokens - Ignored by this method.
Returns:
True.

hasToken

public boolean hasToken()
Return true. This method returns true in all cases to indicate that the next call to get() will succeed without throwing a NoTokenException, as indeed it will, even if not right away. Note that if this were to return true only if a rendezvous was pending, then polymorphic actors would busy wait.

Specified by:
hasToken in interface Receiver
Specified by:
hasToken in class AbstractReceiver
Returns:
True.

hasToken

public boolean hasToken(int tokens)
Return true. This method returns true in all cases to indicate that any number of calls to get() will succeed without throwing a NoTokenException, as indeed they will, even if not right away. Note that if this were to return true only if a rendezvous was pending, then polymorphic actors would busy wait.

Specified by:
hasToken in interface Receiver
Specified by:
hasToken in class AbstractReceiver
Parameters:
tokens - Ignored by this method.
Returns:
True.

isConnectedToBoundary

public boolean isConnectedToBoundary()
                              throws IllegalActionException
Return true if this receiver is connected to the inside of a boundary port. A boundary port is an opaque port that is contained by a composite actor. If this receiver is connected to the inside of a boundary port, then return true; otherwise return false.

Specified by:
isConnectedToBoundary in interface ProcessReceiver
Returns:
True if this receiver is connected to the inside of a boundary port; return false otherwise.
Throws:
IllegalActionException
See Also:
BoundaryDetector

isConnectedToBoundaryInside

public boolean isConnectedToBoundaryInside()
                                    throws InvalidStateException,
                                           IllegalActionException
Return true if this receiver is connected to the inside of a boundary port. A boundary port is an opaque port that is contained by a composite actor. If this receiver is connected to the inside of a boundary port, then return true; otherwise return false.

Specified by:
isConnectedToBoundaryInside in interface ProcessReceiver
Returns:
True if this receiver is connected to the inside of a boundary port; return false otherwise.
Throws:
IllegalActionException
InvalidStateException
See Also:
BoundaryDetector

isConnectedToBoundaryOutside

public boolean isConnectedToBoundaryOutside()
                                     throws IllegalActionException
Return true if this receiver is connected to the outside of a boundary port. A boundary port is an opaque port that is contained by a composite actor. If this receiver is connected to the outside of a boundary port, then return true; otherwise return false.

Specified by:
isConnectedToBoundaryOutside in interface ProcessReceiver
Returns:
True if this receiver is connected to the outside of a boundary port; return false otherwise.
Throws:
IllegalActionException
See Also:
BoundaryDetector

isConsumerReceiver

public boolean isConsumerReceiver()
                           throws IllegalActionException
This class serves as an example of a ConsumerReceiver and hence this method returns true.

Specified by:
isConsumerReceiver in interface ProcessReceiver
Returns:
True if this is a consumer receiver; return false otherwise.
Throws:
IllegalActionException

isInsideBoundary

public boolean isInsideBoundary()
Return true if this receiver is contained on the inside of a boundary port. A boundary port is an opaque port that is contained by a composite actor. If this receiver is contained on the inside of a boundary port then return true; otherwise return false.

Specified by:
isInsideBoundary in interface ProcessReceiver
Returns:
True if this receiver is contained on the inside of a boundary port; return false otherwise.
See Also:
BoundaryDetector

isOutsideBoundary

public boolean isOutsideBoundary()
Return true if this receiver is contained on the outside of a boundary port. A boundary port is an opaque port that is contained by a composite actor. If this receiver is contained on the outside of a boundary port then return true; otherwise return false.

Specified by:
isOutsideBoundary in interface ProcessReceiver
Returns:
True if this receiver is contained on the outside of a boundary port; return false otherwise.
See Also:
BoundaryDetector

isProducerReceiver

public boolean isProducerReceiver()
Return true if this receiver is on an outside or an inside boundary.

Specified by:
isProducerReceiver in interface ProcessReceiver
Returns:
True if this is a producer receiver; return false otherwise.

isReadBlocked

public boolean isReadBlocked()
Return true if there is a get or a conditional receive waiting on this receiver.

Specified by:
isReadBlocked in interface ProcessReceiver
Returns:
True if a read is pending on this receiver.

isWriteBlocked

public boolean isWriteBlocked()
Return true if there is either a put or a conditional send waiting on this receiver.

Specified by:
isWriteBlocked in interface ProcessReceiver
Returns:
A boolean indicating whether a write is pending on this receiver.

put

public void put(Token token)
         throws TerminateProcessException
Put a token into the mailbox receiver. This method does not return until the rendezvous is complete. This method is internally synchronized on the director. If the specified token is null, this method does nothing.

Specified by:
put in interface Receiver
Specified by:
put in class AbstractReceiver
Parameters:
token - The token, or null to do nothing.
Throws:
TerminateProcessException - If the actor to which this receiver belongs has been terminated while still running i.e it was not allowed to run to completion.

putArrayToAll

public void putArrayToAll(Token[] tokens,
                          int numberOfTokens,
                          Receiver[] receivers)
                   throws NoRoomException,
                          IllegalActionException,
                          TerminateProcessException
Put a sequence of tokens to all receivers in the specified array. This method sequentially calls putToAll() for each token in the tokens array.

Specified by:
putArrayToAll in interface Receiver
Overrides:
putArrayToAll in class AbstractReceiver
Parameters:
tokens - The sequence of token to put.
numberOfTokens - The number of tokens to put (the array might be longer).
receivers - The receivers.
Throws:
NoRoomException - If there is no room for the token.
IllegalActionException - If the token is not acceptable to one of the ports (e.g., wrong type), or if the tokens array does not have at least the specified number of tokens.
TerminateProcessException - If the actor to which this receiver belongs has been terminated while still running i.e it was not allowed to run to completion.

putToAll

public void putToAll(Token token,
                     Receiver[] receivers)
              throws NoRoomException,
                     IllegalActionException,
                     TerminateProcessException
Put to all receivers in the specified array. This method starts a thread for each receiver after the first one to perform the put() on that receiver, and then calls put() on the first receiver. Thus, each of the put() calls occurs in a different thread. This method does not return until all the put() calls have succeeded. If the specified token is null, this method does nothing.

Specified by:
putToAll in interface Receiver
Overrides:
putToAll in class AbstractReceiver
Parameters:
token - The token to put, or null to put no token.
receivers - The receivers, which are assumed to all be instances of CSPReceiver.
Throws:
NoRoomException - If there is no room for the token.
IllegalActionException - If the token is not acceptable to one of the ports (e.g., wrong type).
TerminateProcessException - If the actor to which this receiver belongs has been terminated while still running i.e it was not allowed to run to completion.

requestFinish

public void requestFinish()
The model has finished executing, so set a flag so that the next time an actor tries to get or put it gets a TerminateProcessException which will cause it to finish.

Specified by:
requestFinish in interface ProcessReceiver

reset

public void reset()
Reset local flags.

Specified by:
reset in interface ProcessReceiver
Specified by:
reset in interface Receiver
Overrides:
reset in class AbstractReceiver

_checkFlagsAndWait

protected void _checkFlagsAndWait()
                           throws TerminateProcessException,
                                  java.lang.InterruptedException
This method wraps the wait() call between checks on the state of the receiver. The flags checked are whether the receiver has been finished. The actions taken depending on the flags apply to whatever process this method was invoked from.

This method is internally synchronized on the director. To avoid missing events you should the callers also need to be synchronized on the director (this is currently the case).

Throws:
TerminateProcessException - If the actor to which this receiver belongs has been terminated while still running i.e it was not allowed to run to completion.
java.lang.InterruptedException - If the actor is interrupted while waiting(for a rendezvous to complete).

_getOtherController

protected AbstractBranchController _getOtherController()
Return the controller of the conditional branch to reach the rendezvous point first. For a rendezvous to occur when both communications at the receiver are from conditional branches, then the rendezvous can only proceed if both the branches are the first branches to be ready to succeed for their respective controllers. This is checked by the second branch to arrive at the rendezvous point, for which it requires the actor that created the other branch. Thus the first branch to arrive stores its controller in the receiver when it is setting the appropriate flag, which is what is returned by this method.

Returns:
The controller which controls the first conditional branch to arrive.

_getOtherID

protected int _getOtherID()
Return the branch ID of the branch that requested the conditional receive.

Returns:
The branch ID.

_getDirector

protected CSPDirector _getDirector()
Return the director that is controlling the execution of this model. If this receiver is an inside receiver, then it is the director of the container (actor) of the container (port). Otherwise, it is the executive director of the container (actor) of the container (port).

Returns:
The CSPDirector controlling this model.

_isConditionalReceiveWaiting

protected boolean _isConditionalReceiveWaiting()
Return whether a ConditionalReceive is trying to rendezvous with this receiver.

Returns:
True if a ConditionalReceive branch is trying to rendezvous with this receiver.

_isConditionalSendWaiting

protected boolean _isConditionalSendWaiting()
Return whether a ConditionalSend is trying to rendezvous with this receiver.

Returns:
True if a ConditionalSend branch is trying to rendezvous with this receiver.

_isGetWaiting

protected boolean _isGetWaiting()
Return whether a get() is waiting to rendezvous at this receiver.

Returns:
True if a get() is waiting to rendezvous.

_isPutWaiting

protected boolean _isPutWaiting()
Flag indicating whether or not a put() is waiting to rendezvous at this receiver.

Returns:
True if a put() is waiting to rendezvous.

_setConditionalSend

protected void _setConditionalSend(boolean ready,
                                   AbstractBranchController controller,
                                   int otherID)
Set a flag so that a ConditionalReceive branch knows whether or not a ConditionalSend is ready to rendezvous with it.

Parameters:
ready - Boolean indicating whether or not a conditional send is waiting to rendezvous.
controller - The controller which contains the ConditionalSend branch that is trying to rendezvous. It is stored in the receiver so that if a ConditionalReceive arrives, it can easily check whether the ConditionalSend branch was the first branch of its conditional construct(CIF or CDO) to succeed.
otherID - The branch ID of the branch requesting the conditional send.

_setConditionalReceive

protected void _setConditionalReceive(boolean ready,
                                      AbstractBranchController controller,
                                      int otherID)
Set a flag so that a ConditionalSend branch knows whether or not a ConditionalReceive is ready to rendezvous with it.

Parameters:
ready - Boolean indicating whether or not a conditional receive is waiting to rendezvous.
controller - The CSPActor which contains the ConditionalReceive branch that is trying to rendezvous. It is stored in the receiver so that if a ConditionalSend arrives, it can easily check whether the ConditionalReceive branch was the first branch of its conditional construct(CIF or CDO) to succeed.
otherID - The branch ID of the branch requesting the conditional receive.

_checkFlags

private void _checkFlags()
                  throws TerminateProcessException
Check the flags controlling the state of the receiver and hence the actor process trying to rendezvous with it. If the model has finished executing, the _modelFinished flag will have been set and a TerminateProcessException will be thrown causing the actor process to finish.

Throws:
TerminateProcessException - If the actor to which this receiver belongs has been terminated while still running i.e. it was not allowed to run to completion.