Package ikr.simlib.ports

Ports are the main abstraction used for communication between entities.

See: Description

Package ikr.simlib.ports Description

Ports are the main abstraction used for communication between entities. Ports use a handshake protocol to exchange messages. Ports of different entities or ports belonging to the same entity may be connected using the connect() -method of the Entity class. Ports always belong to one entity. Input and output ports are only conceptionally different to make type checking easier. They have the same functionality.

Every port may have several message filters attached to it. They may be used to filter messages, or to get information about messages, e.g. for counting or statistics.
A port may also have one input message handler and one output message handler. Message handlers are the interface between ports and entities. Whenever a message has to be sent, the corresponding message handler is called by the port.

The following protocol is used to exchange messages: If an entity has prepared a new message to send, it calls the messageIndication() -method of its output port. The message then travels along the connected ports to the destination input port. Finally, the handleMsgIndication() -method of the input message handler is responsible of handling the message. If it can handle the message, it immediately calls the getMessage() -method of the input port, which passes the call to the output handler of the source port. The handleGetMessage() -method of this port must then supply the message (active sender).
If getMessage() is not called, the sender is blocked. A receiver port may call isMessageAvailable() which is passed from the input port to the corresponding output port. There, the handleIsMessageAvailable() -method of the output message handler is called (active receiver). getMessage() may only be called within handleMsgIndication() or after a successful isMessageAvaialbale() -call!
The port registers itself automatically at the port manager.

The difference between input and output ports is implemented by the introduction of two special port classes InputPort and OutputPort.



Basic Characteristics of Ports

All ports are derived from the same base class Port . There are sending ports (base class OutputPort) and receiving ports (base class InputPort). This is identified by a field within Port , which can be accessed with getPortType() .
Each port belongs to a certain model component, which must be declared upon initialization as a parameter (owner). In addition, each port has a local name (declared upon constructor call), which must be unique within the model component and together with the global name of the superjacent model component composes the global port name.

Connecting Ports

Two model components are connected by creating a directed connection between two corresponding ports which are to be used for their communication. There are several ways of accomplishing this:

Communication between Ports

A handshake protocol has been defined for the exchange of messages between two model components via ports, which has been realized with three functions:

Sender offers message ("active sender")
  1. Sender entity calls messageIndication() of the output port.
  2. Output port calls messageIndication() of the successor port (= input port of the receiver entity).
  3. Input port calls handleMessageIndication() of its message handler because there is no successor port.
  4. InputMessageHandler calls a handler function of the receiver entity (e.g., handleMessageIndication() ) or reacts directly.
  5. Receiver entity or InputMessageHandler decides if the message can be retrieved at the current time and if necessary calls getMessage() of the input port.
  6. Input port calls getMessage() of the predecessor port (= output port of the sender entity).
  7. Output port calls handleGetMessage() of its message handler, because there is no predecessor port.
  8. Output port calls either a handler function of the sender entity (e.g., handleGetMessage()) or reacts directly.
Simplified
 illustration of events during message exchange
Simplified illustration of events during message exchange


A reference to the sent message finally lands as a return value of the original getMessage() call of the receiver. To be exact, calls made by the messageIndication() and getMessage() methods of a port are not directly delivered to the succeeding or preceding port (steps 2 and 6) or the corresponding message handler (steps 3 and 7). In fact the handler methods of any connected message filters are called first and then the TPort method handleMessageIndication() or handleGetMessage() are called which take care of delivery.

Receiver inquires about the next message ("active receiver")
  1. Receiver entity calls isMessageAvailable() of the input port.
  2. Input port calls isMessageAvailable() of the output port of the sender entity.
  3. Output port calls handleIsMessageAvailable() .
  4. Output port calls either a handler function of the sender entity (e.g., handleIsMessageAvailable() ) or reacts directly. The return value announces if a message is available or not and finally lands at the receiver entity.
  5. The receiver entity generally calls getMessage() of the input port if true is returned.
  6. The input port calls getMessage() of the output port of the sender entity.
  7. The output port calls handleGetMessage() of its message handler because it has no preceding port.
  8. Output portcalls either a handler function of the sender entity (e.g., handleGetMessage() ) or reacts directly.
A reference to the sent message finally lands as a return value of the original getMessage() call by the receiver. The extension and refining of sequences in reference to message filters and the port's own handle<*>() methods as in the "active sender" scenario.

Special Ports

There are several classes that have been derived from InputPort or OutputPort in the simulation library, that have ports which represent specially defined functions: