001/* A ProcessReceiver is an interface for receivers in the process oriented
002 domains.
003
004 Copyright (c) 1997-2015 The Regents of the University of California.
005 All rights reserved.
006 Permission is hereby granted, without written agreement and without
007 license or royalty fees, to use, copy, modify, and distribute this
008 software and its documentation for any purpose, provided that the above
009 copyright notice and the following two paragraphs appear in all copies
010 of this software.
011
012 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
013 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
014 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
015 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
016 SUCH DAMAGE.
017
018 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
019 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
020 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
021 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
022 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
023 ENHANCEMENTS, OR MODIFICATIONS.
024
025 PT_COPYRIGHT_VERSION_2
026 COPYRIGHTENDKEY
027
028 */
029package ptolemy.actor.process;
030
031import ptolemy.actor.Receiver;
032import ptolemy.kernel.util.IllegalActionException;
033import ptolemy.kernel.util.InvalidStateException;
034
035///////////////////////////////////////////////////////////////////
036//// ProcessReceiver
037
038/**
039 A ProcessReceiver is an interface for receivers in the process oriented
040 domains. It adds methods to the Receiver interface for setting flags that
041 indicate whether a termination of the simulation has been requested.
042 In addition, methods are available to accommodate hierarchical
043 heterogeneity via composite actors.
044 <P>
045 In process oriented domains, simulations are normally ended on the
046 detection of a deadlock. During a deadlock, processes or the
047 corresponding threads are normally waiting on a call to some
048 methods (for reading or writing) on a receiver.
049 To terminate or end the simulation, these methods should
050 either return or throw an exception to inform the processes that they
051 should terminate themselves. For this a method requestFinish() is defined.
052 This method would set a local flag in the receivers and wake up all the
053 processes waiting on some call to the receiver. On waking up these
054 processes would see that the termination flag set and behave accordingly.
055 A sample implementation is <BR>
056 <Code>
057 public synchronized void requestFinish() {
058 _terminate = true;
059 notifyAll();
060 }
061 </code>
062 <P>
063 <P>
064 To accommodate hierarchical heterogeneity, an instantiation of
065 ProcessReceiver must be able to determine its topological location
066 with respect to boundary ports. A boundary port is an opaque port
067 that is contained by a composite actor. This ability is enforced
068 with the isConnectedToBoundary(), isConnectedToBoundaryOutside(),
069 isConnectedToBoundaryInside(), isInsideBoundary() and isOutsideBoundary()
070 methods. For convenience, the BoundaryDetector class is available to
071 to simplify the implementation of these methods.
072 <P>
073 Blocking reads and writes are accommodated via the get(Branch)
074 and put(Token, Branch) methods. In cases where a branch attempts
075 to get data from or put data into a process receiver, it calls,
076 respectively, these methods by passing itself as an argument.
077 The process receiver then knows to register any blocks with
078 the branch rather than with a director as is occurs in non-composite
079 cases.
080 <P>
081 Note that it is not necessary for an implementation of ProcessReceiver to
082 be used in the ports of an opaque composite actor. It is perfectly fine
083 for a ProcessReceiver implementation to be used in the ports of an atomic
084 actor. In such cases the get() and put() methods are called without the
085 use of a branch object. If blocking reads or writes occur they are
086 registered with the controlling director without the need for a branch
087 or branch controller.
088
089
090 @author Neil Smyth, Mudit Goel, John S. Davis II
091 @version $Id$
092 @since Ptolemy II 0.2
093 @Pt.ProposedRating Green (mudit)
094 @Pt.AcceptedRating Yellow (mudit)
095 @see ptolemy.actor.process.BoundaryDetector
096
097 */
098public interface ProcessReceiver extends Receiver {
099    ///////////////////////////////////////////////////////////////////
100    ////                         public methods                    ////
101
102    /** Return true if this receiver is connected to the inside of a
103     *  boundary port. A boundary port is an opaque port that is
104     *  contained by a composite actor. If this receiver is connected
105     *  to the inside of a boundary port, then return true; otherwise
106     *  return false.
107     *  <P>
108     *  It is suggested that this method be implemented using
109     *  the BoundaryDetector class although such an implementation
110     *  is not necessary.
111     *  @return True if this receiver is contained on the inside of
112     *   a boundary port; return false otherwise.
113     *  @exception InvalidStateException If thrown by the boundary
114     *   detector.
115     *  @exception IllegalActionException If thrown by the boundary
116     *   detector.
117     *  @see BoundaryDetector
118     */
119    public boolean isConnectedToBoundary() throws IllegalActionException;
120
121    /** Return true if this receiver is connected to the inside of a
122     *  boundary port. A boundary port is an opaque port that is
123     *  contained by a composite actor. If this receiver is connected
124     *  to the inside of a boundary port, then return true; otherwise
125     *  return false.
126     *  <P>
127     *  It is suggested that this method be implemented using
128     *  the BoundaryDetector class although such an implementation
129     *  is not necessary.
130     *  @return True if this receiver is contained on the inside of
131     *   a boundary port; return false otherwise.
132     *  @exception IllegalActionException If thrown by the boundary
133     *   detector.
134     *  @exception InvalidStateException If thrown by the boundary
135     *   detector.
136     *  @see BoundaryDetector
137     */
138    public boolean isConnectedToBoundaryInside()
139            throws InvalidStateException, IllegalActionException;
140
141    /** Return true if this receiver is connected to the outside of a
142     *  boundary port. A boundary port is an opaque port that is
143     *  contained by a composite actor. If this receiver is connected
144     *  to the outside of a boundary port, then return true; otherwise
145     *  return false.
146     *  <P>
147     *  It is suggested that this method be implemented using
148     *  the BoundaryDetector class although such an implementation
149     *  is not necessary.
150     *  @return True if this receiver is contained on the outside of
151     *   a boundary port; return false otherwise.
152     *  @exception IllegalActionException If thrown by the boundary
153     *   detector.
154     *  @see BoundaryDetector
155     */
156    public boolean isConnectedToBoundaryOutside() throws IllegalActionException;
157
158    /** Return true if this receiver is a consumer receiver. A process
159     *  receiver is a consumer receiver if it is connected to a
160     *  boundary port.
161     *  @return True if this is a consumer receiver; return
162     *   false otherwise.
163     *  @exception IllegalActionException If thrown by the boundary
164     *   detector.
165     */
166    public boolean isConsumerReceiver() throws IllegalActionException;
167
168    /** Return true if this receiver is contained on the inside of a
169     *  boundary port. A boundary port is an opaque port that is
170     *  contained by a composite actor. If this receiver is contained
171     *  on the inside of a boundary port then return true; otherwise
172     *  return false.
173     *  <P>
174     *  It is suggested that this method be implemented using
175     *  the BoundaryDetector class although such an implementation
176     *  is not necessary.
177     *  @return True if this receiver is contained on the inside of
178     *   a boundary port; return false otherwise.
179     *  @see BoundaryDetector
180     */
181    public boolean isInsideBoundary();
182
183    /** Return true if this receiver is contained on the outside of a
184     *  boundary port. A boundary port is an opaque port that is
185     *  contained by a composite actor. If this receiver is contained
186     *  on the outside of a boundary port then return true; otherwise
187     *  return false.
188     *  <P>
189     *  It is suggested that this method be implemented using
190     *  the BoundaryDetector class although such an implementation
191     *  is not necessary.
192     *  @return True if this receiver is contained on the outside of
193     *   a boundary port; return false otherwise.
194     *  @see BoundaryDetector
195     */
196    public boolean isOutsideBoundary();
197
198    /** Return true if this receiver is a producer receiver. A process
199     *  receiver is a producer receiver if it is contained on the
200     *  inside or outside of a boundary port.
201     *  @return True if this is a producer receiver; return false
202     *   otherwise.
203     */
204    public boolean isProducerReceiver();
205
206    /** Determine whether this receiver is read blocked.
207     *  @return True if this receiver is read blocked and
208     *   false otherwise.
209     */
210    public boolean isReadBlocked();
211
212    /** Determine whether this receiver is write blocked.
213     *  @return True if this receiver is write blocked and
214     *   false otherwise.
215     */
216    public boolean isWriteBlocked();
217
218    /** Set a local flag requesting that the simulation be finished.
219     */
220    public void requestFinish();
221
222    /** Reset the local flags of this receiver. Use this method when
223     *  restarting execution.
224     */
225    @Override
226    public void reset();
227}