Exemplo n.º 1
0
DataLink*
MulticastTransport::find_datalink_i(const RepoId& /*local_id*/,
                                    const RepoId& remote_id,
                                    const TransportBLOB& /*remote_data*/,
                                    CORBA::Long /*priority*/,
                                    bool active)
{
  // To accommodate the one-to-many nature of multicast reservations,
  // a session layer is used to maintain state between unique pairs
  // of DomainParticipants over a single DataLink instance. Given
  // that TransportImpl instances may only be attached to either
  // Subscribers or Publishers within the same DomainParticipant,
  // it may be assumed that the local_id always references the same
  // participant.
  MulticastDataLink_rch link;
  if (active && !this->client_link_.is_nil()) {
    link = this->client_link_;
  }

  if (!active && !this->server_link_.is_nil()) {
    link = this->server_link_;
  }

  if (!link.is_nil()) {

    MulticastPeer remote_peer = RepoIdConverter(remote_id).participantId();

    MulticastSession_rch session = link->find_session(remote_peer);

    if (session.is_nil()) {
      // From the framework's point-of-view, no DataLink was found.
      // This way we will progress to the connect/accept stage for handshaking.
      return 0;
    }

    if (!session->start(active)) {
      ACE_ERROR_RETURN((LM_ERROR,
                        ACE_TEXT("(%P|%t) ERROR: ")
                        ACE_TEXT("MulticastTransport[%C]::find_datalink_i: ")
                        ACE_TEXT("failed to start session for remote peer: 0x%x!\n"),
                        this->config_i_->name().c_str(), remote_peer),
                       0);
    }

    VDBG_LVL((LM_DEBUG, "(%P|%t) MulticastTransport[%C]::find_datalink_i "
              "started session for remote peer: 0x%x\n",
              this->config_i_->name().c_str(), remote_peer), 2);
  }

  return link._retn();
}
Exemplo n.º 2
0
DataLink*
MulticastTransport::accept_datalink(ConnectionEvent& ce)
{
  const std::string ttype = "multicast";
  const CORBA::ULong num_blobs = ce.remote_association_.remote_data_.length();
  const RepoId& remote_id = ce.remote_association_.remote_id_;
  MulticastPeer remote_peer = RepoIdConverter(remote_id).participantId();

  ACE_GUARD_RETURN(ACE_SYNCH_MUTEX, guard, this->connections_lock_, 0);

  for (CORBA::ULong idx = 0; idx < num_blobs; ++idx) {
    if (ce.remote_association_.remote_data_[idx].transport_type.in() == ttype) {

      MulticastDataLink_rch link = this->server_link_;
      if (link.is_nil()) {
        link = this->make_datalink(ce.local_id_, remote_id,
                                   ce.priority_, false /*!active*/);
        this->server_link_ = link;
      }

      if (this->connections_.count(remote_peer)) {
        // remote_peer has already completed the handshake
        VDBG_LVL((LM_DEBUG, "(%P|%t) MulticastTransport[%C]::accept_datalink "
                  "peer 0x%x already completed handshake\n",
                  this->config_i_->name().c_str(), remote_peer), 2);
        return link._retn();
      }

      this->pending_connections_.insert(
        std::pair<ConnectionEvent* const, MulticastPeer>(&ce, remote_peer));

      guard.release(); // start_session() called without connections_lock_,
      // at this point we know we will return and not need the lock again.

      VDBG_LVL((LM_DEBUG, "(%P|%t) MulticastTransport[%C]::accept_datalink "
                "starting session for peer 0x%x\n",
                this->config_i_->name().c_str(), remote_peer), 2);

      MulticastSession_rch session = this->start_session(link, remote_peer,
                                                         false /*!active*/);
      // Can't return link to framework until handshaking is done, which will
      // result in a call to MulticastTransport::passive_connection().
      return 0;
    }
  }
  return 0;
}
Exemplo n.º 3
0
DataLink*
MulticastTransport::connect_datalink_i(const RepoId& local_id,
                                       const RepoId& remote_id,
                                       const TransportBLOB& /*remote_data*/,
                                       CORBA::Long priority)
{
  MulticastDataLink_rch link = this->client_link_;
  if (link.is_nil()) {
    link = this->make_datalink(local_id, remote_id, priority, true /*active*/);
    this->client_link_ = link;
  }

  MulticastPeer remote_peer = RepoIdConverter(remote_id).participantId();

  MulticastSession_rch session =
    this->start_session(link, remote_peer, true /*active*/);
  if (session.is_nil()) {
    return 0; // already logged in start_session()
  }

  if (remote_peer == RepoIdConverter(local_id).participantId()) {
    VDBG_LVL((LM_DEBUG, "(%P|%t) MulticastTransport[%C]::connect_datalink_i "
              "loopback on peer: 0x%x, skipping wait_for_ack\n",
              this->config_i_->name().c_str(), remote_peer), 2);
    return link._retn();
  }

  VDBG_LVL((LM_DEBUG, "(%P|%t) MulticastTransport[%C]::connect_datalink_i "
            "waiting for ack from: 0x%x\n",
            this->config_i_->name().c_str(), remote_peer), 2);

  if (session->wait_for_ack()) {
    VDBG_LVL((LM_DEBUG, "(%P|%t) MulticastTransport::connect_datalink_i "
              "done waiting for ack\n"), 2);
    return link._retn();
  }

  VDBG_LVL((LM_DEBUG, "(%P|%t) MulticastTransport::connect_datalink_i "
            "wait for ack failed\n"), 2);
  return 0;
}