LCOV - code coverage report
Current view: top level - eq/server - node.cpp (source / functions) Hit Total Coverage
Test: Equalizer Lines: 156 363 43.0 %
Date: 2016-07-30 05:04:55 Functions: 33 55 60.0 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2005-2016, Stefan Eilemann <eile@equalizergraphics.com>
       3             :  *                          Daniel Nachbaur <danielnachbaur@gmail.com>
       4             :  *                          Cedric Stalder <cedric.stalder@gmail.com>
       5             :  *
       6             :  * This library is free software; you can redistribute it and/or modify it under
       7             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       8             :  * by the Free Software Foundation.
       9             :  *
      10             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      11             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      12             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      13             :  * details.
      14             :  *
      15             :  * You should have received a copy of the GNU Lesser General Public License
      16             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      17             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      18             :  */
      19             : 
      20             : #include "node.h"
      21             : 
      22             : #include "channel.h"
      23             : #include "config.h"
      24             : #include "global.h"
      25             : #include "log.h"
      26             : #include "nodeFactory.h"
      27             : #include "pipe.h"
      28             : #include "server.h"
      29             : #include "window.h"
      30             : 
      31             : #include <eq/fabric/commands.h>
      32             : #include <eq/fabric/elementVisitor.h>
      33             : #include <eq/fabric/event.h>
      34             : #include <eq/fabric/paths.h>
      35             : 
      36             : #include <co/barrier.h>
      37             : #include <co/global.h>
      38             : #include <co/objectICommand.h>
      39             : 
      40             : #include <lunchbox/clock.h>
      41             : #include <lunchbox/os.h>
      42             : #include <lunchbox/sleep.h>
      43             : 
      44             : #include <boost/filesystem/operations.hpp>
      45             : #include <boost/filesystem/path.hpp>
      46             : 
      47             : namespace eq
      48             : {
      49             : namespace server
      50             : {
      51             : typedef fabric::Node< Config, Node, Pipe, NodeVisitor > Super;
      52             : typedef co::CommandFunc<Node> NodeFunc;
      53             : namespace
      54             : {
      55             : #define S_MAKE_ATTR_STRING( attr ) ( std::string("EQ_NODE_") + #attr )
      56          56 : std::string _sAttributeStrings[] = {
      57             :     S_MAKE_ATTR_STRING( SATTR_LAUNCH_COMMAND )
      58          28 : };
      59          56 : std::string _cAttributeStrings[] = {
      60             :     S_MAKE_ATTR_STRING( CATTR_LAUNCH_COMMAND_QUOTE )
      61          28 : };
      62             : 
      63           0 : void _addEnv( std::ostringstream& stream, const char* key )
      64             : {
      65           0 :     char* env = getenv( key );
      66           0 :     if( env )
      67           0 :         stream << key << "=" << env << " ";
      68           0 : }
      69             : }
      70             : 
      71         862 : Node::Node( Config* parent )
      72             :     : Super( parent )
      73             :     , _active( 0 )
      74             :     , _finishedFrame( 0 )
      75             :     , _flushedFrame( 0 )
      76             :     , _state( STATE_STOPPED )
      77         862 :     , _bufferedTasks( new co::BufferConnection )
      78        1724 :     , _lastDrawPipe( 0 )
      79             : {
      80         862 :     const Global* global = Global::instance();
      81        1724 :     for( int i=0; i < Node::SATTR_LAST; ++i )
      82             :     {
      83         862 :         const SAttribute attr = static_cast< SAttribute >( i );
      84         862 :         setSAttribute( attr, global->getNodeSAttribute( attr ));
      85             :     }
      86        1724 :     for( int i=0; i < Node::CATTR_LAST; ++i )
      87             :     {
      88         862 :         const CAttribute attr = static_cast< CAttribute >( i );
      89         862 :         setCAttribute( attr, global->getNodeCAttribute( attr ));
      90             :     }
      91        3448 :     for( int i = 0; i < IATTR_LAST; ++i )
      92             :     {
      93        2586 :         const IAttribute attr = static_cast< IAttribute >( i );
      94        2586 :         setIAttribute( attr, global->getNodeIAttribute( attr ));
      95             :     }
      96         862 : }
      97             : 
      98        1720 : Node::~Node()
      99             : {
     100        1720 : }
     101             : 
     102           4 : void Node::attach( const uint128_t& id, const uint32_t instanceID )
     103             : {
     104           4 :     Super::attach( id, instanceID );
     105             : 
     106           4 :     co::CommandQueue* cmdQ = getCommandThreadQueue();
     107             :     registerCommand( fabric::CMD_OBJECT_SYNC,
     108           4 :                      NodeFunc( this, &Node::_cmdSync ), cmdQ );
     109             :     registerCommand( fabric::CMD_NODE_CONFIG_INIT_REPLY,
     110           4 :                      NodeFunc( this, &Node::_cmdConfigInitReply ), cmdQ );
     111             :     registerCommand( fabric::CMD_NODE_CONFIG_EXIT_REPLY,
     112           4 :                      NodeFunc( this, &Node::_cmdConfigExitReply ), cmdQ );
     113             :     registerCommand( fabric::CMD_NODE_FRAME_FINISH_REPLY,
     114           4 :                      NodeFunc( this, &Node::_cmdFrameFinishReply ), cmdQ );
     115           4 : }
     116             : 
     117          20 : ServerPtr Node::getServer()
     118             : {
     119          20 :     return getConfig() ? getConfig()->getServer() : 0;
     120             : }
     121             : 
     122           0 : ConstServerPtr Node::getServer() const
     123             : {
     124           0 :     return getConfig() ? getConfig()->getServer() : 0;
     125             : }
     126             : 
     127          12 : co::CommandQueue* Node::getMainThreadQueue()
     128             : {
     129          12 :     return getConfig()->getMainThreadQueue();
     130             : }
     131             : 
     132          20 : co::CommandQueue* Node::getCommandThreadQueue()
     133             : {
     134          20 :     return getConfig()->getCommandThreadQueue();
     135             : }
     136             : 
     137           0 : Channel* Node::getChannel( const ChannelPath& path )
     138             : {
     139           0 :     const Pipes& pipes = getPipes();
     140           0 :     LBASSERT( pipes.size() > path.pipeIndex );
     141             : 
     142           0 :     if( pipes.size() <= path.pipeIndex )
     143           0 :         return 0;
     144             : 
     145           0 :     return pipes[ path.pipeIndex ]->getChannel( path );
     146             : }
     147             : 
     148           4 : void Node::addTasks( const uint32_t tasks )
     149             : {
     150           4 :     setTasks( getTasks() | tasks );
     151           4 : }
     152             : 
     153           2 : void Node::activate()
     154             : {
     155           2 :     ++_active;
     156           2 :     LBLOG( LOG_VIEW ) << "activate: " << _active << std::endl;
     157           2 : }
     158             : 
     159           2 : void Node::deactivate()
     160             : {
     161           2 :     LBASSERT( _active != 0 );
     162           2 :     --_active;
     163           2 :     LBLOG( LOG_VIEW ) << "deactivate: " << _active << std::endl;
     164           2 : };
     165             : 
     166         862 : void Node::setSAttribute( const SAttribute attr, const std::string& value )
     167             : {
     168         862 :     _sAttributes[attr] = value;
     169         862 : }
     170             : 
     171         432 : const std::string& Node::getSAttribute( const SAttribute attr ) const
     172             : {
     173         432 :     return _sAttributes[attr];
     174             : }
     175             : 
     176         682 : const std::string& Node::getSAttributeString( const SAttribute attr )
     177             : {
     178         682 :     return _sAttributeStrings[attr];
     179             : }
     180             : 
     181         862 : void Node::setCAttribute( const CAttribute attr, const char value )
     182             : {
     183         862 :     _cAttributes[attr] = value;
     184         862 : }
     185             : 
     186         432 : char Node::getCAttribute( const CAttribute attr ) const
     187             : {
     188         432 :     return _cAttributes[attr];
     189             : }
     190             : 
     191         682 : const std::string& Node::getCAttributeString( const CAttribute attr )
     192             : {
     193         682 :     return _cAttributeStrings[attr];
     194             : }
     195             : 
     196             : //===========================================================================
     197             : // Operations
     198             : //===========================================================================
     199             : 
     200             : //---------------------------------------------------------------------------
     201             : // launch and connect
     202             : //---------------------------------------------------------------------------
     203             : 
     204             : namespace
     205             : {
     206           0 : class NetNode : public co::Node
     207             : {
     208             : public:
     209           0 :     NetNode( server::Node& node ) : co::Node(), _node( node ) {}
     210             : 
     211             : private:
     212             :     server::Node& _node;
     213             : 
     214           0 :     std::string getWorkDir() const override
     215           0 :         { return _node.getConfig()->getWorkDir(); }
     216             : 
     217           0 :     std::string getLaunchQuote() const override
     218             :     {
     219             :         return std::string( 1, _node.getCAttribute(
     220           0 :                                     server::Node::CATTR_LAUNCH_COMMAND_QUOTE ));
     221             :     }
     222             : };
     223             : 
     224           0 : static co::NodePtr _createNetNode( Node* node )
     225             : {
     226           0 :     co::NodePtr netNode = new NetNode( *node );
     227             :     const co::ConnectionDescriptions& descriptions =
     228           0 :         node->getConnectionDescriptions();
     229           0 :     for( co::ConnectionDescriptionPtr desc : descriptions )
     230             :     {
     231             :         netNode->addConnectionDescription(
     232           0 :             new co::ConnectionDescription( *desc ));
     233             : 
     234           0 :         if( node->getHost().empty( ))
     235             :         {
     236           0 :             node->setHost( desc->getHostname( ));
     237           0 :             LBWARN << "No host specified, guessing " << node->getHost()
     238           0 :                    << " from " << desc << std::endl;
     239             :         }
     240           0 :     }
     241             : 
     242           0 :     netNode->setHostname( node->getHost( ));
     243           0 :     return netNode;
     244             : }
     245             : }
     246             : 
     247           2 : bool Node::connect()
     248             : {
     249           2 :     LBASSERT( isActive( ));
     250             : 
     251           2 :     if( _node )
     252           2 :         return _node->isConnected();
     253             : 
     254           0 :     if( !isStopped( ))
     255             :     {
     256           0 :         LBASSERT( _state == STATE_FAILED );
     257           0 :         return true;
     258             :     }
     259             : 
     260           0 :     co::LocalNodePtr localNode = getLocalNode();
     261           0 :     LBASSERT( localNode );
     262             : 
     263           0 :     _node = _createNetNode( this );
     264             : 
     265           0 :     LBLOG( LOG_INIT ) << "Connecting node" << std::endl;
     266           0 :     if( localNode->connect( _node ) ||
     267           0 :         localNode->launch( _node, _createLaunchCommand( )))
     268             :     {
     269           0 :         return true;
     270             :     }
     271             : 
     272           0 :     LBWARN << "Connection to " << _node->getNodeID() << " failed" << std::endl;
     273           0 :     _state = STATE_FAILED;
     274           0 :     _node = nullptr;
     275           0 :     return false;
     276             : }
     277             : 
     278           2 : bool Node::syncLaunch( const lunchbox::Clock& clock )
     279             : {
     280           2 :     LBASSERT( isActive( ));
     281             : 
     282           2 :     if( !_node )
     283           0 :         return false;
     284             : 
     285           2 :     if( _node->isConnected( ))
     286           2 :         return true;
     287             : 
     288           0 :     LBASSERT( !isApplicationNode( ));
     289             : 
     290           0 :     co::LocalNodePtr localNode = getLocalNode();
     291           0 :     const int64_t timeOut = getIAttribute( IATTR_LAUNCH_TIMEOUT );
     292           0 :     _node = localNode->syncLaunch( _node->getNodeID(),
     293             :                                    std::max( int64_t( 0 ),
     294           0 :                                              timeOut - clock.getTime64( )));
     295           0 :     if( _node )
     296           0 :         return true;
     297             : 
     298           0 :     sendError( fabric::ERROR_NODE_CONNECT ) << _host;
     299           0 :     _state = STATE_FAILED;
     300           0 :     return false;
     301             : }
     302             : 
     303           0 : std::string Node::_createLaunchCommand() const
     304             : {
     305           0 :     const std::string& command = getSAttribute( SATTR_LAUNCH_COMMAND );
     306           0 :     const size_t commandPos = command.find( "%c" );
     307           0 :     if( commandPos == std::string::npos )
     308           0 :         return command + " " + _createRemoteCommand();
     309             : 
     310           0 :     return command.substr( 0, commandPos ) + _createRemoteCommand() +
     311           0 :            command.substr( commandPos + 1 );
     312             : }
     313             : 
     314           0 : std::string Node::_createRemoteCommand() const
     315             : {
     316           0 :     const Config* config = getConfig();
     317           0 :     std::string program = config->getRenderClient();
     318           0 :     if( program.empty( ))
     319             :     {
     320           0 :         LBWARN << "No render client name, auto-launch will fail" << std::endl;
     321           0 :         return program;
     322             :     }
     323             : 
     324             :     //----- environment
     325           0 :     std::ostringstream os;
     326           0 :     const std::string& quote = _node->getLaunchQuote();
     327             : 
     328             :     //----- program + args
     329             : #ifndef WIN32
     330             : #  ifdef Darwin
     331             :     const char libPath[] = "DYLD_LIBRARY_PATH";
     332             : #  else
     333           0 :     const char libPath[] = "LD_LIBRARY_PATH";
     334             : #  endif
     335             : 
     336           0 :     os << "env ";
     337           0 :     _addEnv( os, libPath );
     338           0 :     _addEnv( os, "PATH" );
     339           0 :     _addEnv( os, "PYTHONPATH" );
     340             : 
     341           0 :     for( int i=0; environ[i] != 0; ++i )
     342             :     {
     343           0 :         if( strlen( environ[i] ) > 2 &&
     344           0 :             ( strncmp( environ[i], "LB_", 3 ) == 0 ||
     345           0 :               strncmp( environ[i], "CO_", 3 ) == 0 ||
     346           0 :               strncmp( environ[i], "EQ_", 3 ) == 0 ))
     347             :         {
     348           0 :             os << quote << environ[i] << quote << " ";
     349             :         }
     350             :     }
     351             : 
     352           0 :     os << "LB_LOG_LEVEL=" <<lunchbox::Log::getLogLevelString() << " ";
     353           0 :     if( lunchbox::Log::topics != 0 )
     354           0 :         os << "LB_LOG_TOPICS=" <<lunchbox::Log::topics << " ";
     355             : #endif
     356             : 
     357             :     const boost::filesystem::path absolute =
     358           0 :         boost::filesystem::system_complete( boost::filesystem::path( program ));
     359           0 :     program = absolute.string();
     360             : 
     361           0 :     return os.str() + quote + program + quote + " -- --eq-client %o ";
     362             : }
     363             : 
     364             : //---------------------------------------------------------------------------
     365             : // init
     366             : //---------------------------------------------------------------------------
     367           2 : void Node::configInit( const uint128_t& initID, const uint32_t frameNumber )
     368             : {
     369           2 :     LBASSERT( _state == STATE_STOPPED );
     370           2 :     _state = STATE_INITIALIZING;
     371             : 
     372           2 :     const Config* config = getConfig();
     373           2 :     _flushedFrame  = config->getFinishedFrame();
     374           2 :     _finishedFrame = config->getFinishedFrame();
     375           2 :     _frameIDs.clear();
     376             : 
     377           2 :     LBLOG( LOG_INIT ) << "Create node" << std::endl;
     378           2 :     getConfig()->send( _node, fabric::CMD_CONFIG_CREATE_NODE ) << getID();
     379             : 
     380           2 :     LBLOG( LOG_INIT ) << "Init node" << std::endl;
     381           2 :     send( fabric::CMD_NODE_CONFIG_INIT ) << initID << frameNumber;
     382           2 : }
     383             : 
     384           2 : bool Node::syncConfigInit()
     385             : {
     386           2 :     LBASSERT( _state == STATE_INITIALIZING || _state == STATE_INIT_SUCCESS ||
     387             :               _state == STATE_INIT_FAILED );
     388             : 
     389           2 :     _state.waitNE( STATE_INITIALIZING );
     390             : 
     391           2 :     if( _state == STATE_INIT_SUCCESS )
     392             :     {
     393           2 :         _state = STATE_RUNNING;
     394           2 :         return true;
     395             :     }
     396             : 
     397           0 :     LBWARN << "Node initialization failed" << std::endl;
     398           0 :     configExit();
     399           0 :     return false;
     400             : }
     401             : 
     402             : //---------------------------------------------------------------------------
     403             : // exit
     404             : //---------------------------------------------------------------------------
     405           2 : void Node::configExit()
     406             : {
     407           2 :     if( _state == STATE_EXITING )
     408           2 :         return;
     409             : 
     410           2 :     LBASSERT( _state == STATE_RUNNING || _state == STATE_INIT_FAILED );
     411           2 :     _state = STATE_EXITING;
     412             : 
     413           2 :     LBLOG( LOG_INIT ) << "Exit node" << std::endl;
     414           2 :     send( fabric::CMD_NODE_CONFIG_EXIT );
     415           2 :     flushSendBuffer();
     416             : }
     417             : 
     418           2 : bool Node::syncConfigExit()
     419             : {
     420           2 :     LBASSERT( _state == STATE_EXITING || _state == STATE_EXIT_SUCCESS ||
     421             :               _state == STATE_EXIT_FAILED );
     422             : 
     423           2 :     _state.waitNE( STATE_EXITING );
     424           2 :     const bool success = ( _state == STATE_EXIT_SUCCESS );
     425           2 :     LBASSERT( success || _state == STATE_EXIT_FAILED );
     426             : 
     427           2 :     _state = isActive() ? STATE_FAILED : STATE_STOPPED;
     428           2 :     setTasks( fabric::TASK_NONE );
     429           2 :     _frameIDs.clear();
     430           2 :     _flushBarriers();
     431           2 :     return success;
     432             : }
     433             : 
     434             : //---------------------------------------------------------------------------
     435             : // update
     436             : //---------------------------------------------------------------------------
     437           0 : void Node::update( const uint128_t& frameID, const uint32_t frameNumber )
     438             : {
     439           0 :     if( !isRunning( ))
     440           0 :         return;
     441             : 
     442           0 :     LBVERB << "Start frame " << frameNumber << std::endl;
     443           0 :     LBASSERT( isActive( ));
     444             : 
     445           0 :     _frameIDs[ frameNumber ] = frameID;
     446             : 
     447           0 :     uint128_t configVersion = co::VERSION_INVALID;
     448           0 :     if( !isApplicationNode( )) // synced in Config::_cmdFrameStart
     449           0 :         configVersion = getConfig()->getVersion();
     450             : 
     451             :     send( fabric::CMD_NODE_FRAME_START )
     452           0 :             << getVersion() << configVersion << frameID << frameNumber;
     453           0 :     LBLOG( LOG_TASKS ) << "TASK node start frame " << std::endl;
     454             : 
     455           0 :     const Pipes& pipes = getPipes();
     456           0 :     for( Pipes::const_iterator i = pipes.begin(); i != pipes.end(); ++i )
     457           0 :         (*i)->update( frameID, frameNumber );
     458             : 
     459           0 :     if( !_lastDrawPipe ) // no FrameDrawFinish sent
     460             :     {
     461           0 :         send( fabric::CMD_NODE_FRAME_DRAW_FINISH ) << frameID << frameNumber;
     462           0 :         LBLOG( LOG_TASKS ) << "TASK node draw finish " << getName() <<  " "
     463           0 :                            << std::endl;
     464             :     }
     465           0 :     _lastDrawPipe = 0;
     466             : 
     467           0 :     send( fabric::CMD_NODE_FRAME_TASKS_FINISH ) << frameID << frameNumber;
     468           0 :     LBLOG( LOG_TASKS ) << "TASK node tasks finish " << std::endl;
     469             : 
     470           0 :     _finish( frameNumber );
     471           0 :     flushSendBuffer();
     472             : }
     473             : 
     474           0 : uint32_t Node::_getFinishLatency() const
     475             : {
     476           0 :     switch( getIAttribute( Node::IATTR_THREAD_MODEL ))
     477             :     {
     478             :         case fabric::UNDEFINED:
     479             :         case fabric::DRAW_SYNC:
     480           0 :             if( getTasks() & fabric::TASK_DRAW )
     481             :             {
     482             :                 // More than one frame latency doesn't make sense, since the
     483             :                 // draw sync for frame+1 does not allow for more
     484           0 :                 const Config* config = getConfig();
     485           0 :                 const uint32_t latency = config->getLatency();
     486             : 
     487           0 :                 return LB_MIN( latency, 1 );
     488             :             }
     489           0 :             break;
     490             : 
     491             :         case fabric::LOCAL_SYNC:
     492           0 :             if( getTasks() != fabric::TASK_NONE )
     493             :                 // local sync enforces no latency
     494           0 :                 return 0;
     495           0 :             break;
     496             : 
     497             :         case fabric::ASYNC:
     498           0 :             break;
     499             :         default:
     500           0 :             LBUNIMPLEMENTED;
     501             :     }
     502             : 
     503           0 :     const Config* config = getConfig();
     504           0 :     return config->getLatency();
     505             : }
     506             : 
     507           0 : void Node::_finish( const uint32_t currentFrame )
     508             : {
     509           0 :     const Pipes& pipes = getPipes();
     510           0 :     for( Pipes::const_iterator i = pipes.begin(); i != pipes.end(); ++i )
     511             :     {
     512           0 :         const Pipe* pipe = *i;
     513           0 :         if( pipe->getIAttribute( Pipe::IATTR_HINT_THREAD ) && pipe->isRunning())
     514             :         {
     515           0 :             const uint32_t latency = _getFinishLatency();
     516           0 :             if( currentFrame > latency )
     517           0 :                 flushFrames( currentFrame - latency );
     518           0 :             return;
     519             :         }
     520             :     }
     521             : 
     522             :     // else only non-threaded pipes, all local tasks are done, send finish now.
     523           0 :     flushFrames( currentFrame );
     524             : }
     525             : 
     526           0 : void Node::flushFrames( const uint32_t frameNumber )
     527             : {
     528           0 :     LBLOG( LOG_TASKS ) << "Flush frames including " << frameNumber << std::endl;
     529             : 
     530           0 :     while( _flushedFrame < frameNumber )
     531             :     {
     532           0 :         ++_flushedFrame;
     533           0 :         _sendFrameFinish( _flushedFrame );
     534             :     }
     535             : 
     536           0 :     flushSendBuffer();
     537           0 : }
     538             : 
     539           0 : void Node::_sendFrameFinish( const uint32_t frameNumber )
     540             : {
     541           0 :     FrameIDHash::iterator i = _frameIDs.find( frameNumber );
     542           0 :     if( i == _frameIDs.end( ))
     543           0 :         return; // finish already send
     544             : 
     545           0 :     send( fabric::CMD_NODE_FRAME_FINISH ) << i->second << frameNumber;
     546           0 :     _frameIDs.erase( i );
     547           0 :     LBLOG( LOG_TASKS ) << "TASK node finish frame " << frameNumber << std::endl;
     548             : }
     549             : 
     550             : //---------------------------------------------------------------------------
     551             : // Barrier cache
     552             : //---------------------------------------------------------------------------
     553           0 : co::Barrier* Node::getBarrier()
     554             : {
     555           0 :     if( _barriers.empty( ))
     556             :     {
     557             :         co::Barrier* barrier = new co::Barrier( getServer(),
     558           0 :                                                 _node->getNodeID( ));
     559           0 :         barrier->setAutoObsolete( getConfig()->getLatency() + 1 );
     560           0 :         return barrier;
     561             :     }
     562             :     // else
     563             : 
     564           0 :     co::Barrier* barrier = _barriers.back();
     565           0 :     _barriers.pop_back();
     566           0 :     barrier->setHeight( 0 );
     567           0 :     return barrier;
     568             : }
     569             : 
     570           0 : void Node::changeLatency( const uint32_t latency )
     571             : {
     572           0 :     for( co::Barriers::const_iterator i = _barriers.begin();
     573           0 :          i != _barriers.end(); ++ i )
     574             :     {
     575           0 :         co::Barrier* barrier = *i;
     576           0 :         barrier->setAutoObsolete( latency + 1 );
     577             :     }
     578           0 : }
     579             : 
     580           0 : void Node::releaseBarrier( co::Barrier* barrier )
     581             : {
     582           0 :     _barriers.push_back( barrier );
     583           0 : }
     584             : 
     585           2 : void Node::_flushBarriers()
     586             : {
     587           2 :     for( co::BarriersCIter i =_barriers.begin(); i != _barriers.end(); ++i )
     588           0 :         delete *i;
     589           2 :     _barriers.clear();
     590           2 : }
     591             : 
     592           0 : bool Node::removeConnectionDescription( co::ConnectionDescriptionPtr cd )
     593             : {
     594             :     // Don't use std::find, RefPtr::operator== compares pointers, not values.
     595           0 :     for(co::ConnectionDescriptions::iterator i=_connectionDescriptions.begin();
     596           0 :         i != _connectionDescriptions.end(); ++i )
     597             :     {
     598           0 :         if( *cd != **i )
     599           0 :             continue;
     600             : 
     601           0 :         _connectionDescriptions.erase( i );
     602           0 :         return true;
     603             :     }
     604           0 :     return false;
     605             : }
     606             : 
     607           4 : co::ObjectOCommand Node::send( const uint32_t cmd )
     608             : {
     609           4 :     return send( cmd, getID( ));
     610             : }
     611             : 
     612          22 : co::ObjectOCommand Node::send( const uint32_t cmd, const uint128_t& id )
     613             : {
     614             :     return co::ObjectOCommand( co::Connections( 1, _bufferedTasks ), cmd,
     615          22 :                                co::COMMANDTYPE_OBJECT, id, CO_INSTANCE_ALL );
     616             : }
     617             : 
     618           0 : EventOCommand Node::sendError( const uint32_t error )
     619             : {
     620           0 :     return getConfig()->sendError( Event::NODE_ERROR, Error( error, getID( )));
     621             : }
     622             : 
     623          12 : void Node::flushSendBuffer()
     624             : {
     625          12 :     _bufferedTasks->sendBuffer( _node->getConnection( ));
     626          12 : }
     627             : 
     628             : //===========================================================================
     629             : // command handling
     630             : //===========================================================================
     631           2 : bool Node::_cmdConfigInitReply( co::ICommand& cmd )
     632             : {
     633           2 :     co::ObjectICommand command( cmd );
     634           2 :     LBVERB << "handle configInit reply " << command << std::endl;
     635           2 :     LBASSERT( _state == STATE_INITIALIZING );
     636           2 :     _state = command.read< uint64_t >() ? STATE_INIT_SUCCESS : STATE_INIT_FAILED;
     637             : 
     638           2 :     return true;
     639             : }
     640             : 
     641           2 : bool Node::_cmdConfigExitReply( co::ICommand& cmd )
     642             : {
     643           2 :     co::ObjectICommand command( cmd );
     644           2 :     LBVERB << "handle configExit reply " << command << std::endl;
     645           2 :     LBASSERT( _state == STATE_EXITING );
     646             : 
     647           2 :     _state = command.read< bool >() ? STATE_EXIT_SUCCESS : STATE_EXIT_FAILED;
     648           2 :     return true;
     649             : }
     650             : 
     651           0 : bool Node::_cmdFrameFinishReply( co::ICommand& cmd )
     652             : {
     653           0 :     co::ObjectICommand command( cmd );
     654           0 :     LBVERB << "handle frame finish reply " << command << std::endl;
     655             : 
     656           0 :     const uint32_t frameNumber = command.read< uint32_t >();
     657             : 
     658           0 :     _finishedFrame = frameNumber;
     659           0 :     getConfig()->notifyNodeFrameFinished( frameNumber );
     660             : 
     661           0 :     return true;
     662             : }
     663             : 
     664         432 : void Node::output( std::ostream& os ) const
     665             : {
     666         432 :     if( !_host.empty( ))
     667         258 :         os << "host     \"" << _host << '"' << std::endl;
     668             : 
     669         432 :     const co::ConnectionDescriptions& descriptions = _connectionDescriptions;
     670        2202 :     for( co::ConnectionDescriptions::const_iterator i = descriptions.begin();
     671        1468 :          i != descriptions.end(); ++i )
     672             :     {
     673         302 :         co::ConnectionDescriptionPtr desc = *i;
     674         302 :         os << *desc;
     675         302 :     }
     676             : 
     677         432 :     bool attrPrinted   = false;
     678             : 
     679        1728 :     for( Node::SAttribute i = static_cast<Node::SAttribute>( 0 );
     680         864 :          i < Node::SATTR_LAST;
     681             :          i = static_cast<Node::SAttribute>( static_cast<uint32_t>( i )+1))
     682             :     {
     683         432 :         const std::string& value = getSAttribute( i );
     684         432 :         if( value == Global::instance()->getNodeSAttribute( i ))
     685         432 :             continue;
     686             : 
     687           0 :         if( !attrPrinted )
     688             :         {
     689           0 :             os << std::endl << "attributes" << std::endl;
     690           0 :             os << "{" << std::endl << lunchbox::indent;
     691           0 :             attrPrinted = true;
     692             :         }
     693             : 
     694             :         os << ( i==Node::SATTR_LAUNCH_COMMAND ? "launch_command       " :
     695           0 :                 "ERROR" )
     696           0 :            << "\"" << value << "\"" << std::endl;
     697             :     }
     698             : 
     699        1728 :     for( Node::CAttribute i = static_cast<Node::CAttribute>( 0 );
     700         864 :          i < Node::CATTR_LAST;
     701             :          i = static_cast<Node::CAttribute>( static_cast<uint32_t>( i )+1))
     702             :     {
     703         432 :         const char value = getCAttribute( i );
     704         432 :         if( value == Global::instance()->getNodeCAttribute( i ))
     705         432 :             continue;
     706             : 
     707           0 :         if( !attrPrinted )
     708             :         {
     709           0 :             os << std::endl << "attributes" << std::endl;
     710           0 :             os << "{" << std::endl << lunchbox::indent;
     711           0 :             attrPrinted = true;
     712             :         }
     713             : 
     714             :         os << ( i==Node::CATTR_LAUNCH_COMMAND_QUOTE ? "launch_command_quote " :
     715           0 :                 "ERROR" )
     716           0 :            << "'" << value << "'" << std::endl;
     717             :     }
     718             : 
     719        3456 :     for( Node::IAttribute i = static_cast< Node::IAttribute>( 0 );
     720        1728 :          i < Node::IATTR_LAST;
     721             :          i = static_cast< Node::IAttribute >( static_cast<uint32_t>( i )+1))
     722             :     {
     723        1296 :         const int value = getIAttribute( i );
     724        1296 :         if( value == Global::instance()->getNodeIAttribute( i ))
     725        1296 :             continue;
     726             : 
     727           0 :         if( !attrPrinted )
     728             :         {
     729           0 :             os << std::endl << "attributes" << std::endl;
     730           0 :             os << "{" << std::endl << lunchbox::indent;
     731           0 :             attrPrinted = true;
     732             :         }
     733             : 
     734             :         os << ( i== Node::IATTR_LAUNCH_TIMEOUT ? "launch_timeout       " :
     735             :                 i== Node::IATTR_THREAD_MODEL   ? "thread_model         " :
     736             :                 i== Node::IATTR_HINT_AFFINITY  ? "hint_affinity        " :
     737           0 :                 "ERROR" )
     738           0 :            << static_cast< fabric::IAttribute >( value ) << std::endl;
     739             :     }
     740             : 
     741         432 :     if( attrPrinted )
     742           0 :         os << lunchbox::exdent << "}" << std::endl << std::endl;
     743         432 : }
     744             : 
     745             : }
     746             : }
     747             : 
     748             : #include "../fabric/node.ipp"
     749             : template class eq::fabric::Node< eq::server::Config, eq::server::Node,
     750             :                                  eq::server::Pipe, eq::server::NodeVisitor >;
     751             : /** @cond IGNORE */
     752             : template std::ostream& eq::fabric::operator << ( std::ostream&,
     753          84 :                                                  const eq::server::Super& );
     754             : /** @endcond */

Generated by: LCOV version 1.11