bool Server::_cmdUnmap( co::Command& command ) { co::NodePtr node = command.getNode(); co::Nodes::iterator i = stde::find( _admins, node ); EQASSERT( i != _admins.end( )); if( i != _admins.end( )) { _admins.erase( i ); const Configs& configs = getConfigs(); for( Configs::const_iterator j = configs.begin(); j != configs.end(); ++j ) { Config* config = *j; fabric::ServerDestroyConfigPacket destroyConfigPacket; destroyConfigPacket.configID = config->getID(); node->send( destroyConfigPacket ); } } const admin::ServerUnmapPacket* packet = command.get< admin::ServerUnmapPacket >(); admin::ServerUnmapReplyPacket reply( packet ); node->send( reply ); return true; }
bool Node::_cmdConfigInit( co::Command& command ) { LB_TS_THREAD( _nodeThread ); const NodeConfigInitPacket* packet = command.get<NodeConfigInitPacket>(); LBLOG( LOG_INIT ) << "Init node " << packet << std::endl; _state = STATE_INITIALIZING; _currentFrame = packet->frameNumber; _unlockedFrame = packet->frameNumber; _finishedFrame = packet->frameNumber; _setAffinity(); transmitter.start(); setError( ERROR_NONE ); NodeConfigInitReplyPacket reply; reply.result = configInit( packet->initID ); if( getIAttribute( IATTR_THREAD_MODEL ) == eq::UNDEFINED ) setIAttribute( IATTR_THREAD_MODEL, eq::DRAW_SYNC ); _state = reply.result ? STATE_RUNNING : STATE_INIT_FAILED; commit(); send( command.getNode(), reply ); return true; }
//--------------------------------------------------------------------------- // command handlers //--------------------------------------------------------------------------- bool Config::_cmdInit( co::Command& command ) { EQ_TS_THREAD( _mainThread ); const ConfigInitPacket* packet = command.get<ConfigInitPacket>(); EQVERB << "handle config start init " << packet << std::endl; sync(); setError( ERROR_NONE ); commit(); ConfigInitReplyPacket reply( packet ); reply.result = _init( packet->initID ); if( !reply.result ) exit(); sync(); EQINFO << "Config init " << (reply.result ? "successful: ": "failed: ") << getError() << std::endl; reply.version = commit(); send( command.getNode(), reply ); setError( ERROR_NONE ); return true; }
bool Window::_cmdConfigInit( co::Command& command ) { const WindowConfigInitPacket* packet = command.get<WindowConfigInitPacket>(); LBLOG( LOG_INIT ) << "TASK window config init " << packet << std::endl; WindowConfigInitReplyPacket reply; setError( ERROR_NONE ); if( getPipe()->isRunning( )) { _state = STATE_INITIALIZING; reply.result = configInit( packet->initID ); if( reply.result ) _state = STATE_RUNNING; } else { setError( ERROR_WINDOW_PIPE_NOTRUNNING ); reply.result = false; } LBLOG( LOG_INIT ) << "TASK window config init reply " << &reply <<std::endl; commit(); send( command.getNode(), reply ); return true; }
bool Config::_cmdUpdate( co::Command& command ) { const ConfigUpdatePacket* packet = command.get<ConfigUpdatePacket>(); EQVERB << "handle config update " << packet << std::endl; sync(); setError( ERROR_NONE ); commit(); co::NodePtr node = command.getNode(); if( !_needsFinish ) { ConfigUpdateVersionPacket reply( packet, getVersion(), EQ_UNDEFINED_UINT32 ); send( node, reply ); return true; } co::LocalNodePtr localNode = getLocalNode(); ConfigUpdateVersionPacket replyVersion( packet, getVersion(), localNode->registerRequest( )); send( node, replyVersion ); _flushAllFrames(); _finishedFrame.waitEQ( _currentFrame ); // wait for render clients idle localNode->waitRequest( replyVersion.requestID ); // wait for app sync _needsFinish = false; ConfigUpdateReplyPacket reply( packet ); reply.result = _updateRunning(); if( !reply.result && getIAttribute( IATTR_ROBUSTNESS ) == OFF ) { EQWARN << "Config update failed, exiting config: " << getError() << std::endl; exit(); } reply.version = commit(); send( command.getNode(), reply ); return true; }
bool Config::_cmdExit( co::Command& command ) { const ConfigExitPacket* packet = command.get<ConfigExitPacket>(); ConfigExitReplyPacket reply( packet ); EQVERB << "handle config exit " << packet << std::endl; setError( ERROR_NONE ); if( _state == STATE_RUNNING ) reply.result = exit(); else reply.result = false; EQINFO << "config exit result: " << reply.result << std::endl; send( command.getNode(), reply ); return true; }
bool Server::_cmdReleaseConfig( co::Command& command ) { const ServerReleaseConfigPacket* packet = command.get<ServerReleaseConfigPacket>(); EQINFO << "Handle release config " << packet << std::endl; ServerReleaseConfigReplyPacket reply( packet ); co::NodePtr node = command.getNode(); Config* config = 0; const Configs& configs = getConfigs(); for( Configs::const_iterator i = configs.begin(); i != configs.end() && !config; ++i ) { Config* candidate = *i; if( candidate->getID() == packet->configID ) config = candidate; } if( !config ) { EQWARN << "Release request for unknown config" << std::endl; node->send( reply ); return true; } if( config->isRunning( )) { EQWARN << "Release of running configuration" << std::endl; config->exit(); // Make sure config is exited } fabric::ServerDestroyConfigPacket destroyConfigPacket; destroyConfigPacket.requestID = registerRequest(); destroyConfigPacket.configID = config->getID(); node->send( destroyConfigPacket ); waitRequest( destroyConfigPacket.requestID ); ConfigRestoreVisitor restore; config->accept( restore ); node->send( reply ); EQLOG( co::base::LOG_ANY ) << "----- Released Config -----" << std::endl; return true; }
bool Config::_cmdStartFrame( co::Command& command ) { const ConfigStartFramePacket* packet = command.get<ConfigStartFramePacket>(); EQVERB << "handle config frame start " << packet << std::endl; _startFrame( packet->frameID ); if( _state == STATE_STOPPED ) { // unlock app ConfigFrameFinishPacket frameFinishPacket; frameFinishPacket.frameNumber = _currentFrame; send( command.getNode(), frameFinishPacket ); } return true; }
bool Server::_cmdShutdown( co::Command& command ) { const ServerShutdownPacket* packet = command.get< ServerShutdownPacket >(); ServerShutdownReplyPacket reply( packet ); co::NodePtr node = command.getNode(); if( !_admins.empty( )) { EQWARN << "Ignoring shutdown request, " << _admins.size() << " admin clients connected" << std::endl; node->send( reply ); return true; } const Configs& configs = getConfigs(); for( Configs::const_iterator i = configs.begin(); i != configs.end(); ++i ) { Config* candidate = *i; if( candidate->isUsed( )) { EQWARN << "Ignoring shutdown request due to used config" << std::endl; node->send( reply ); return true; } } EQINFO << "Shutting down server" << std::endl; _running = false; reply.result = true; node->send( reply ); #ifndef WIN32 // WAR for 2874188: Lockup at shutdown co::base::sleep( 100 ); #endif return true; }
bool Server::_cmdMap( co::Command& command ) { co::NodePtr node = command.getNode(); _admins.push_back( node ); const Configs& configs = getConfigs(); for( Configs::const_iterator i = configs.begin(); i != configs.end(); ++i ) { Config* config = *i; fabric::ServerCreateConfigPacket createConfigPacket( config ); node->send( createConfigPacket ); } const admin::ServerMapPacket* packet = command.get< admin::ServerMapPacket >(); admin::ServerMapReplyPacket reply( packet ); node->send( reply ); return true; }
bool Node::_cmdFrameFinish( co::Command& command ) { LB_TS_THREAD( _nodeThread ); const NodeFrameFinishPacket* packet = command.get<NodeFrameFinishPacket>(); LBLOG( LOG_TASKS ) << "TASK frame finish " << getName() << " " << packet << std::endl; const uint32_t frameNumber = packet->frameNumber; _finishFrame( frameNumber ); _frameFinish( packet->frameID, frameNumber ); const uint128_t version = commit(); if( version != co::VERSION_NONE ) { fabric::ObjectSyncPacket syncPacket; send( command.getNode(), syncPacket ); } return true; }
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; }