Class 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$
    Author:
    Neil Smyth, John S. Davis II, Edward A. Lee
    Pt.AcceptedRating:
    Green (kienhuis)
    Pt.ProposedRating:
    Red (nsmyth)
    • 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

      • 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 - If thrown by the boundary detector.
        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 - If thrown by the boundary detector.
        See Also:
        BoundaryDetector
      • 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
      • _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.