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(); }
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; }
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; }