예제 #1
0
 /** Custom initialization method, called by the enclosing actor, during its initialization. */
 public synchronized void initialize() {
   operationalSourcePorts = new HashSet<IOPort>();
   operationalSourcePorts.addAll(this.sourcePortList());
   if (isInput() && getContainer() instanceof MessageBuffer) {
     MessageBuffer _msgBfr = (MessageBuffer) getContainer();
     if (_msgBfr.acceptInputPort(this)) {
       Receiver[][] receivers = getReceivers();
       for (int i = 0; i < receivers.length; i++) {
         Receiver[] receivers2 = receivers[i];
         for (int j = 0; j < receivers2.length; j++) {
           Receiver receiver = receivers2[j];
           if (receiver instanceof MessageProvider) {
             ((MessageProvider) receiver).setMessageBuffer(_msgBfr);
           }
         }
       }
     } else {
       setMessageBuffer(null);
     }
   }
   //     first need to find a way to register the port statistics
   //     as children of the actor statistics
   statistics.reset();
   StatisticsServiceFactory.getService().registerStatistics(statistics);
 }
예제 #2
0
  /**
   * Send a token to all connected receivers. Tokens are in general immutable, so each receiver is
   * given a reference to the same token and no clones are made. The transfer is accomplished by
   * calling getRemoteReceivers() to determine the number of channels with valid receivers and then
   * calling send() on the appropriate channels. It would probably be faster to call put() directly
   * on the receivers. If there are no destination receivers, then nothing is sent. If the port is
   * not connected to anything, or receivers have not been created in the remote port, then just
   * return.
   *
   * <p>Some of this method is read-synchronized on the workspace. Since it is possible for a thread
   * to block while executing a put, it is important that the thread does not hold read access on
   * the workspace when it is blocked. Thus this method releases read access on the workspace before
   * calling put.
   *
   * @param token The token to send
   * @exception IllegalActionException If the token to be sent cannot be converted to the type of
   *     this port
   * @exception NoRoomException If a send to one of the channels throws it.
   */
  public void broadcast(Token token) throws IllegalActionException, NoRoomException {

    if (logger.isTraceEnabled()) {
      logger.trace("broadcast() - entry : " + token);
    }

    statistics.acceptSentMessage(null);

    Receiver[][] farReceivers;
    // ptolemy debug listener stuff etc
    if (_debugging) {
      _debug("broadcast " + token);
    }
    try {
      _workspace.getReadAccess();
      _checkType(token);
      farReceivers = getRemoteReceivers();
      if (farReceivers == null) {
        return;
      }
    } finally {
      _workspace.doneReading();
    }
    // NOTE: This does not call send() here, because send()
    // repeats the above on each call.
    for (int i = 0; i < farReceivers.length; i++) {
      if (farReceivers[i] == null) continue;
      putAtFarReceivers(token, farReceivers[i]);
    }

    if (logger.isTraceEnabled()) {
      logger.trace("broadcast() - exit");
    }
  }
예제 #3
0
  /**
   * Get a token from the specified channel. If the channel has a group with more than one receiver
   * (something that is possible if this is a transparent port), then this method calls get() on all
   * receivers, but returns only the first non-null token returned by these calls. Normally this
   * method is not used on transparent ports. If there is no token to return, then throw an
   * exception.
   *
   * <p>Some of this method is read-synchronized on the workspace. Since it is possible for a thread
   * to block while executing a get, it is important that the thread does not hold read access on
   * the workspace when it is blocked. Thus this method releases read access on the workspace before
   * calling get().
   *
   * @param channelIndex The channel index.
   * @return A token from the specified channel.
   * @exception NoTokenException If there is no token.
   * @exception IllegalActionException If there is no director, and hence no receivers have been
   *     created, if the port is not an input port, or if the channel index is out of range.
   */
  public Token get(int channelIndex) throws NoTokenException, IllegalActionException {
    if (logger.isTraceEnabled()) {
      logger.trace("get() - entry : channel : " + channelIndex);
    }

    Receiver[][] localReceivers;
    try {
      _workspace.getReadAccess();
      // Note that the getReceivers() method might throw an
      // IllegalActionException if there's no director.
      localReceivers = getReceivers();
      if (channelIndex >= localReceivers.length) {
        if (!isInput()) {
          throw new IllegalActionException(this, "Port is not an input port!");
        } else {
          throw new IllegalActionException(
              this,
              "Channel index "
                  + channelIndex
                  + " is out of range, because width is only "
                  + getWidth()
                  + ".");
        }
      }

      if (localReceivers[channelIndex] == null) {
        throw new NoTokenException(this, "No receiver at index: " + channelIndex + ".");
      }
    } finally {
      _workspace.doneReading();
    }
    Token token = null;
    for (int j = 0; j < localReceivers[channelIndex].length; j++) {
      Token localToken = localReceivers[channelIndex][j].get();
      if (token == null) {
        token = localToken;
      }
    }
    if (token == null) {
      throw new NoTokenException(this, "No token to return.");
    }
    if (_debugging) {
      _debug("get from channel " + channelIndex + ": " + token);
    }
    token = convertTokenForMe(token);

    statistics.acceptReceivedMessage(null);

    if (logger.isTraceEnabled()) {
      logger.trace("get() - exit - result : " + token);
    }
    return token;
  }
예제 #4
0
  /**
   * Send a token to the specified channel, checking the type and converting the token if necessary.
   * If the port is not connected to anything, or receivers have not been created in the remote
   * port, or the channel index is out of range, or the port is not an output port, then just
   * silently return. This behavior makes it easy to leave output ports unconnected when you are not
   * interested in the output. If the type of the specified token is the type of this port, or the
   * token can be converted to that type losslessly, the token is sent to all receivers connected to
   * the specified channel. Otherwise, IllegalActionException is thrown. Before putting the token
   * into the destination receivers, this method also checks the type of the remote input port, and
   * converts the token if necessary. The conversion is done by calling the convert() method of the
   * type of the remote input port.
   *
   * <p>Some of this method is read-synchronized on the workspace. Since it is possible for a thread
   * to block while executing a put, it is important that the thread does not hold read access on
   * the workspace when it is blocked. Thus this method releases read access on the workspace before
   * calling put.
   *
   * @param channelIndex The index of the channel, from 0 to width-1.
   * @param token The token to send.
   * @exception IllegalActionException If the token to be sent cannot be converted to the type of
   *     this port, or if the token is null.
   * @exception NoRoomException If there is no room in the receiver.
   */
  public void send(int channelIndex, Token token) throws IllegalActionException, NoRoomException {
    if (logger.isTraceEnabled()) {
      logger.trace(
          "{} - send() - entry : channel : {} token : {}",
          new Object[] {this.getFullName(), channelIndex, token});
    }
    if (token == null) {
      throw new IllegalActionException(this, "Cannot send a null token.");
    }

    if (!(PasserelleToken.POISON_PILL == token)) {
      statistics.acceptSentMessage(null);
    }

    Receiver[][] farReceivers;
    if (_debugging) {
      _debug("send to channel " + channelIndex + ": " + token);
    }

    if (isDebugged()) {
      event(new IOPortEvent(this, IOPortEvent.SEND, IOPortEvent.ALLCHANNELS, true, token));
    }

    try {
      try {
        _workspace.getReadAccess();
        _checkType(token);

        // Note that the getRemoteReceivers() method doesn't throw
        // any non-runtime exception.
        farReceivers = getRemoteReceivers();
        if (farReceivers == null
            || farReceivers.length <= channelIndex
            || farReceivers[channelIndex] == null) {
          return;
        }
      } finally {
        _workspace.doneReading();
      }

      putAtFarReceivers(token, farReceivers[channelIndex]);
    } catch (ArrayIndexOutOfBoundsException ex) {
      // NOTE: This may occur if the channel index is out of range.
      // This is allowed, just do nothing.
    }

    logger.trace("{} - send() - exit", this.getFullName());
  }
예제 #5
0
  /**
   * Send a token to the specified channel, checking the type and converting the token if necessary.
   * If the port is not connected to anything, or receivers have not been created in the remote
   * port, or the channel index is out of range, or the port is not an output port, then just
   * silently return. This behavior makes it easy to leave output ports unconnected when you are not
   * interested in the output. If the type of the specified token is the type of this port, or the
   * token can be converted to that type losslessly, the token is sent to all receivers connected to
   * the specified channel. Otherwise, IllegalActionException is thrown. Before putting the token
   * into the destination receivers, this method also checks the type of the remote input port, and
   * converts the token if necessary. The conversion is done by calling the convert() method of the
   * type of the remote input port.
   *
   * <p>Some of this method is read-synchronized on the workspace. Since it is possible for a thread
   * to block while executing a put, it is important that the thread does not hold read access on
   * the workspace when it is blocked. Thus this method releases read access on the workspace before
   * calling put.
   *
   * @param channelIndex The index of the channel, from 0 to width-1.
   * @param token The token to send.
   * @exception IllegalActionException If the token to be sent cannot be converted to the type of
   *     this port, or if the token is null.
   * @exception NoRoomException If there is no room in the receiver.
   */
  public void send(int channelIndex, Token token) throws IllegalActionException, NoRoomException {
    if (logger.isTraceEnabled()) {
      logger.trace("send() - entry : channel : " + channelIndex + " token : " + token);
    }
    if (token == null) {
      throw new IllegalActionException(this, "Cannot send a null token.");
    }

    statistics.acceptSentMessage(null);

    Receiver[][] farReceivers;
    if (_debugging) {
      _debug("send to channel " + channelIndex + ": " + token);
    }
    try {
      try {
        _workspace.getReadAccess();
        _checkType(token);

        // Note that the getRemoteReceivers() method doesn't throw
        // any non-runtime exception.
        farReceivers = getRemoteReceivers();
        if (farReceivers == null
            || farReceivers.length <= channelIndex
            || farReceivers[channelIndex] == null) {
          return;
        }
      } finally {
        _workspace.doneReading();
      }

      putAtFarReceivers(token, farReceivers[channelIndex]);
    } catch (ArrayIndexOutOfBoundsException ex) {
      // NOTE: This may occur if the channel index is out of range.
      // This is allowed, just do nothing.
    }

    if (logger.isTraceEnabled()) {
      logger.trace("send() - exit");
    }
  }
예제 #6
0
  /**
   * Send a token to all connected receivers. Tokens are in general immutable, so each receiver is
   * given a reference to the same token and no clones are made. The transfer is accomplished by
   * calling getRemoteReceivers() to determine the number of channels with valid receivers and then
   * calling send() on the appropriate channels. It would probably be faster to call put() directly
   * on the receivers. If there are no destination receivers, then nothing is sent. If the port is
   * not connected to anything, or receivers have not been created in the remote port, then just
   * return.
   *
   * <p>Some of this method is read-synchronized on the workspace. Since it is possible for a thread
   * to block while executing a put, it is important that the thread does not hold read access on
   * the workspace when it is blocked. Thus this method releases read access on the workspace before
   * calling put.
   *
   * @param token The token to send
   * @exception IllegalActionException If the token to be sent cannot be converted to the type of
   *     this port
   * @exception NoRoomException If a send to one of the channels throws it.
   */
  public void broadcast(Token token) throws IllegalActionException, NoRoomException {
    logger.trace("{} - broadcast() - entry : {} ", this.getFullName(), token);

    if (!(PasserelleToken.POISON_PILL == token)) {
      statistics.acceptSentMessage(null);
    }

    Receiver[][] farReceivers;
    // ptolemy debug listener stuff etc
    if (_debugging) {
      _debug("broadcast " + token);
    }

    if (isDebugged()) {
      event(new IOPortEvent(this, IOPortEvent.SEND, IOPortEvent.ALLCHANNELS, true, token));
    }

    try {
      _workspace.getReadAccess();
      _checkType(token);
      farReceivers = getRemoteReceivers();
      if (farReceivers == null) {
        return;
      }
    } finally {
      _workspace.doneReading();
    }
    // NOTE: This does not call send() here, because send()
    // repeats the above on each call.
    for (int i = 0; i < farReceivers.length; i++) {
      if (farReceivers[i] == null) continue;
      putAtFarReceivers(token, farReceivers[i]);
    }

    logger.trace("{} - broadcast() - exit", this.getFullName());
  }