Beispiel #1
0
void LocalNode::_connectMulticast( NodePtr node )
{
    EQASSERT( _inReceiverThread( ));
    base::ScopedMutex<> mutex( _outMulticast );

    if( node->_outMulticast.data.isValid( ))
        // multicast already connected by previous _cmdID
        return;

    // Search if the connected node is in the same multicast group as we are
    ConnectionDescriptions descriptions = getConnectionDescriptions();
    for( ConnectionDescriptions::const_iterator i = descriptions.begin();
         i != descriptions.end(); ++i )
    {
        ConnectionDescriptionPtr description = *i;
        if( description->type < CONNECTIONTYPE_MULTICAST )
            continue;

        const ConnectionDescriptions& fromDescs =
            node->getConnectionDescriptions();
        for( ConnectionDescriptions::const_iterator j = fromDescs.begin();
             j != fromDescs.end(); ++j )
        {
            ConnectionDescriptionPtr fromDescription = *j;
            if( !description->isSameMulticastGroup( fromDescription ))
                continue;
            
            EQASSERT( !node->_outMulticast.data );
            EQASSERT( node->_multicasts.empty( ));

            if( _outMulticast->isValid() && 
                _outMulticast.data->getDescription() == description )
            {
                node->_outMulticast.data = _outMulticast.data;
                EQINFO << "Using " << description << " as multicast group for "
                       << node->getNodeID() << std::endl;
            }
            // find unused multicast connection to node
            else for( MCDatas::const_iterator k = _multicasts.begin();
                      k != _multicasts.end(); ++k )
            {
                const MCData& data = *k;
                ConnectionDescriptionPtr dataDesc = 
                    data.connection->getDescription();
                if( !description->isSameMulticastGroup( dataDesc ))
                    continue;

                node->_multicasts.push_back( data );
                EQINFO << "Adding " << dataDesc << " as multicast group for "
                       << node->getNodeID() << std::endl;
            }
        }
    }
}
Beispiel #2
0
bool LocalNode::listen()
{
    EQVERB << "Listener data: " << serialize() << std::endl;
    if( !isClosed() || !_connectSelf( ))
        return false;

    ConnectionDescriptions descriptions = getConnectionDescriptions();
    for( ConnectionDescriptions::const_iterator i =
             descriptions.begin(); i != descriptions.end(); ++i )
    {
        ConnectionDescriptionPtr description = *i;
        ConnectionPtr connection = Connection::create( description );

        if( !connection )
            continue;

        if( !connection->listen( ))
        {
            EQWARN << "Can't create listener connection: " << description
                   << std::endl;
            return false;
        }

        _connectionNodes[ connection ] = this;
        _incoming.addConnection( connection );
        if( description->type >= CONNECTIONTYPE_MULTICAST )
        {
            MCData data;
            data.connection = connection;
            data.node = this;
            _multicasts.push_back( data );
        }

        connection->acceptNB();

        EQVERB << "Added node " << _id << " using " << connection << std::endl;
    }
    
    _state = STATE_LISTENING;
    
    EQVERB << base::className( this ) << " start command and receiver thread "
           << std::endl;
    _receiverThread->start();

    EQINFO << *this << std::endl;
    return true;
}
Beispiel #3
0
bool Server::_cmdChooseConfig( co::Command& command ) 
{
    const ServerChooseConfigPacket* packet = 
        command.get<ServerChooseConfigPacket>();
    EQINFO << "Handle choose config " << packet << std::endl;

    Config* config = 0;
    const Configs& configs = getConfigs();
    for( Configs::const_iterator i = configs.begin();
         i != configs.end() && !config; ++i )
    {
        Config* candidate = *i;
        const float version = candidate->getFAttribute(Config::FATTR_VERSION);
        EQASSERT( version == 1.2f );
        if( !candidate->isUsed() && version == 1.2f)
            config = candidate;
    }
    
    ServerChooseConfigReplyPacket reply( packet );
    co::NodePtr node = command.getNode();

    if( !config )
    {
        reply.configID = UUID::ZERO;
        node->send( reply );
        return true;
    }

    ConfigBackupVisitor backup;
    config->accept( backup );

    const std::string  rendererInfo = packet->rendererInfo;
    const size_t       colonPos     = rendererInfo.find( '#' );
    const std::string  workDir      = rendererInfo.substr( 0, colonPos );
    const std::string  renderClient = rendererInfo.substr( colonPos + 1 );

    config->setApplicationNetNode( node );
    config->setWorkDir( workDir );
    config->setRenderClient( renderClient );
    config->commit();

    fabric::ServerCreateConfigPacket createConfigPacket( config );
    node->send( createConfigPacket );

    reply.configID = config->getID();
    server::Node* appNode = config->findApplicationNode();
    const co::ConnectionDescriptions& descs = 
        appNode->getConnectionDescriptions();

    if( config->getNodes().size() > 1 )
    {
        if( descs.empty() && node->getConnectionDescriptions().empty( ))
        {
            EQWARN << "Likely misconfiguration: Neither the application nor the"
                   << " config file has a connection for this multi-node "
                   << "config. Render clients will be unable to communicate "
                   << "with the application process." << std::endl;
        }
        if( getConnectionDescriptions().empty( ))
        {
            EQWARN << "Likely misconfiguration: The server has no listening "
                   << "connection for this multi-node config. Render clients "
                   << "will be unable to communicate with the server."
                   << std::endl;
        }
    }

    node->send( reply, co::serialize( descs ));
    return true;
}
Beispiel #4
0
bool Server::_cmdChooseConfig( co::ICommand& command )
{
    const uint32_t requestID = command.get< uint32_t >();
    const fabric::ConfigParams& params = command.get< fabric::ConfigParams >();

    LBVERB << "Handle choose config " << command << " req " << requestID
           << " renderer " << params.getWorkDir() << '/'
           << params.getRenderClient() << std::endl;

    Config* config = 0;
    const Configs& configs = getConfigs();
    for( ConfigsCIter i = configs.begin(); i != configs.end() && !config; ++i )
    {
        Config* candidate = *i;
        const float version = candidate->getFAttribute( Config::FATTR_VERSION );
        LBASSERT( version == 1.2f );
        if( !candidate->isUsed() && version == 1.2f )
            config = candidate;
    }

#ifdef EQUALIZER_USE_HWSD
    if( !config )
    {
        const std::string& configFile = command.get< std::string >();
        config = config::Server::configure( this, configFile, params );
        if( config )
        {
            config->register_();
            LBINFO << "Configured\n" << *this << std::endl;
        }
    }
#endif

    co::NodePtr node = command.getNode();

    if( !config )
    {
        node->send( fabric::CMD_SERVER_CHOOSE_CONFIG_REPLY )
            << UUID() << requestID;
        return true;
    }

    ConfigBackupVisitor backup;
    config->accept( backup );
    config->setApplicationNetNode( node );
    config->setWorkDir( params.getWorkDir( ));
    config->setRenderClient( params.getRenderClient( ));
    config->commit();

    node->send( fabric::CMD_SERVER_CREATE_CONFIG )
            << co::ObjectVersion( config ) << LB_UNDEFINED_UINT32;

    server::Node* appNode = config->findApplicationNode();
    const co::ConnectionDescriptions& descs =
        appNode->getConnectionDescriptions();

    if( config->getNodes().size() > 1 )
    {
        if( descs.empty() && node->getConnectionDescriptions().empty( ))
        {
            LBWARN << "Likely misconfiguration: Neither the application nor the"
                   << " config file has a connection for this multi-node "
                   << "config. Render clients will be unable to communicate "
                   << "with the application process." << std::endl;
        }
        if( getConnectionDescriptions().empty( ))
        {
            LBWARN << "Likely misconfiguration: The server has no listening "
                   << "connection for this multi-node config. Render clients "
                   << "will be unable to communicate with the server."
                   << std::endl;
        }
    }

    node->send( fabric::CMD_SERVER_CHOOSE_CONFIG_REPLY )
            << config->getID() << requestID << co::serialize( descs );
    return true;
}