public class ConditionalReceive extends ConditionalBranch implements java.lang.Runnable
It is one branch of either a CDO or a CIF conditional communication construct.
The branches used in a conditional communication construct are controlled by the chooseBranch() method of ConditionalBranchController.
Each branch is created to perform one communication. If more than one branch is enabled (the guard is true or absent), then a thread is created for each enabled branch to try and perform the appropriate rendezvous. If the branch succeeds and is allowed to rendezvous, then it registers itself with the controller and the thread it is running in dies. Otherwise it continues to try and rendezvous until it succeeds or it is notified that another branch has succeeded in with its rendezvous, in which case this branch has failed and the thread it is running in dies.
For rendezvous, the receiver is the key synchronization point. The receiver with which this branch will try to rendezvous is set upon instantiation. It is determined from the port and channel which is passed in in the constructor.
The algorithm by which a branch determines whether or not it has
succeeded with its rendezvous is executed in the run method. There are
roughly three parts to the algorithm, each of which is relevant
to the different rendezvous scenarios.
Case 1: There is a put already waiting
at the rendezvous point. In this case
the branch attempts to register itself, with the controller, as the first
branch ready to rendezvous. If it succeeds, it performs the rendezvous,
notifies the controller that it succeeded and returns. If it is not the first,
it keeps on trying to register itself until it finally succeeds or another
branch successfully rendezvoused in which case it fails and terminates. Note
that a put cannot "go away" so it remains in an inner-loop trying to
rendezvous or failing.
Case 2: There is a conditional send
waiting. In this case it tries to register both branches with their
controllers as the first to try. If it
succeeds it performs the transfer, notifies the controller and returns. It
performs the registration in two steps, first registering this branch and
then registering the other branch. If it successfully registers this branch,
but cannot register the other, it unregisters itself as the first branch
trying, and starts trying to rendezvous from the beginning. This is because
the conditional send could "go away". If it is unable to register itself as
the first branch to try, it again starts trying to rendezvous from the
beginning.
Case 3: If there is neither a put or a
conditional send waiting, it sets a
flag in the receiver that a conditional receive is trying to rendezvous. It
then waits until a put is executed on the receiver, or until another branch
succeeds and this branch fails. If this branch fails, it resets the flag in
the receiver, notifies the controller and returns. Note that it only needs
to wait on a put as if a conditional send is executed on the receiver, it is
the branch which is responsible for checking that the rendezvous can proceed.
Thus, in the case where two conditional branches are trying to rendezvous
at a receiver, it is the responsibility of the branch arriving second to
check that the rendezvous can proceed(see case 2).
ConditionalBranch
Red (eal) |
Green (eal) |
_debugging, _guard
Constructor and Description |
---|
ConditionalReceive(boolean guard,
IOPort port,
int channel,
int branch)
Create a guarded communication with a get() communication.
|
ConditionalReceive(boolean guard,
IOPort port,
int channel,
int branch,
ConditionalBranchController cbc)
Create a guarded communication with a get() communication.
|
ConditionalReceive(IOPort port,
int channel,
int branch)
Create a conditional receive.
|
Modifier and Type | Method and Description |
---|---|
protected boolean |
_isReady()
Return true if this conditional branch is ready to rendezvous
or has already completed its rendezvous.
|
void |
run()
The run method has roughly three parts: (1) where there is already
a put waiting, (2) where there is a ConditionalSend waiting, and
(3) where the ConditionalReceive is the first to arrive at the
receiver.
|
_debug, _setAlive, _setReceivers, _setToken, addDebugListener, getController, getGuard, getID, getPort, getReceivers, getToken, isAlive, removeDebugListener
public ConditionalReceive(IOPort port, int channel, int branch) throws IllegalActionException
port
- The IOPort containing the channel (and thus receiver)
that this branch will try to rendezvous with.channel
- The channel in the IOPort that this branch is
trying to rendezvous with.branch
- The identification number assigned to this branch
upon creation by the CSPActor.IllegalActionException
- If the channel has more
than one receiver or if the receiver is not of type CSPReceiver.public ConditionalReceive(boolean guard, IOPort port, int channel, int branch) throws IllegalActionException
guard
- The guard for the guarded communication statement
represented by this object.port
- The IOPort containing the channel (and thus receiver)
that this branch will try to rendezvous with.channel
- The channel in the IOPort that this branch is
trying to rendezvous with.branch
- The identification number assigned to this branch
upon creation by the CSPActor.IllegalActionException
- If the channel has more
than one receiver or if the receiver is not of type CSPReceiver.public ConditionalReceive(boolean guard, IOPort port, int channel, int branch, ConditionalBranchController cbc) throws IllegalActionException
guard
- The guard for the guarded communication statement
represented by this object.port
- The IOPort containing the channel (and thus receiver)
that this branch will try to rendezvous with.channel
- The channel in the IOPort that this branch is
trying to rendezvous with.branch
- The identification number assigned to this branch
upon creation by the CSPActor.cbc
- The ConditionalBranchController that this branch uses.IllegalActionException
- If the channel has more
than one receiver or if the receiver is not of type CSPReceiver.public void run()
The algorithm used in this method, together with some methods in ConditionalBranchController, control how conditional communication takes place in the CSP domain.
run
in interface java.lang.Runnable
protected boolean _isReady()
_isReady
in class ConditionalBranch