LCOV - code coverage report
Current view: top level - eq/fabric - node.ipp (source / functions) Hit Total Coverage
Test: Equalizer Lines: 137 157 87.3 %
Date: 2016-07-30 05:04:55 Functions: 36 80 45.0 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2010-2014, Stefan Eilemann <eile@eyescale.ch>
       3             :  *                    2010, Cedric Stalder <cedric.stalder@gmail.com>
       4             :  *
       5             :  * This library is free software; you can redistribute it and/or modify it under
       6             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       7             :  * by the Free Software Foundation.
       8             :  *
       9             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      10             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      11             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      12             :  * details.
      13             :  *
      14             :  * You should have received a copy of the GNU Lesser General Public License
      15             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      16             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      17             :  */
      18             : 
      19             : #include "node.h"
      20             : 
      21             : #include "elementVisitor.h"
      22             : #include "leafVisitor.h"
      23             : #include "log.h"
      24             : #include "paths.h"
      25             : 
      26             : #include <co/dataIStream.h>
      27             : #include <co/dataOStream.h>
      28             : 
      29             : namespace eq
      30             : {
      31             : namespace fabric
      32             : {
      33             : namespace
      34             : {
      35             : #define MAKE_ATTR_STRING( attr ) ( std::string("EQ_NODE_") + #attr )
      36             : 
      37         140 : std::string _iAttributeStrings[] = {
      38             :     MAKE_ATTR_STRING( IATTR_THREAD_MODEL ),
      39             :     MAKE_ATTR_STRING( IATTR_LAUNCH_TIMEOUT ),
      40             :     MAKE_ATTR_STRING( IATTR_HINT_AFFINITY )
      41          70 : };
      42             : 
      43             : }
      44             : 
      45             : template< class C, class N, class P, class V >
      46         893 : Node< C, N, P, V >::Node( C* parent )
      47             :         : _config( parent )
      48         893 :         , _isAppNode( false )
      49             : {
      50         893 :     parent->_addNode( static_cast< N* >( this ) );
      51         893 :     LBLOG( LOG_INIT ) << "New " << lunchbox::className( this ) << std::endl;
      52         893 : }
      53             : 
      54             : template< class C, class N, class P, class V >
      55         861 : Node< C, N, P, V >::~Node()
      56             : {
      57         861 :     LBLOG( LOG_INIT ) << "Delete " << lunchbox::className( this ) << std::endl;
      58        2866 :     while( !_pipes.empty() )
      59             :     {
      60        1144 :         P* pipe = _pipes.back();
      61        1144 :         LBASSERT( pipe->getNode() == static_cast< N* >( this ) );
      62        1144 :         _removePipe( pipe );
      63        1144 :         delete pipe;
      64             :     }
      65             : 
      66         861 :     _config->_removeNode( static_cast< N* >( this ) );
      67        1722 : }
      68             : 
      69             : template< class C, class N, class P, class V >
      70        1786 : Node< C, N, P, V >::BackupData::BackupData()
      71             : {
      72        1786 :     memset( iAttributes, 0xff, IATTR_ALL * sizeof( int32_t ));
      73        1786 : }
      74             : 
      75             : template< class C, class N, class P, class V >
      76           4 : void Node< C, N, P, V >::backup()
      77             : {
      78           4 :     Object::backup();
      79           4 :     _backup = _data;
      80           4 : }
      81             : 
      82             : template< class C, class N, class P, class V >
      83           4 : void Node< C, N, P, V >::restore()
      84             : {
      85           4 :     _data = _backup;
      86           4 :     Object::restore();
      87           4 : }
      88             : 
      89             : template< class C, class N, class P, class V >
      90           9 : uint128_t Node< C, N, P, V >::commit( const uint32_t incarnation )
      91             : {
      92           9 :     if( Serializable::isDirty( DIRTY_PIPES ))
      93           8 :         commitChildren( _pipes, incarnation );
      94           9 :     return Object::commit( incarnation );
      95             : }
      96             : 
      97             : template< class C, class N, class P, class V > void
      98           3 : Node< C, N, P, V >::serialize( co::DataOStream& os, const uint64_t dirtyBits )
      99             : {
     100           3 :     Object::serialize( os, dirtyBits );
     101           3 :     if( dirtyBits & DIRTY_ATTRIBUTES )
     102           3 :         os << co::Array< int32_t >( _data.iAttributes, IATTR_ALL );
     103           3 :     if( dirtyBits & DIRTY_PIPES && isMaster( ))
     104             :     {
     105           2 :         os << _mapNodeObjects();
     106           2 :         os.serializeChildren( _pipes );
     107             :     }
     108           3 :     if( dirtyBits & DIRTY_MEMBER )
     109           2 :         os << _isAppNode;
     110           3 : }
     111             : 
     112             : template< class C, class N, class P, class V > void
     113           3 : Node< C, N, P, V >::deserialize( co::DataIStream& is, const uint64_t dirtyBits)
     114             : {
     115           3 :     Object::deserialize( is, dirtyBits );
     116           3 :     if( dirtyBits & DIRTY_ATTRIBUTES )
     117           3 :         is >> co::Array< int32_t >( _data.iAttributes, IATTR_ALL );
     118           3 :     if( dirtyBits & DIRTY_PIPES )
     119             :     {
     120           1 :         if( isMaster( ))
     121           0 :             syncChildren( _pipes );
     122             :         else
     123             :         {
     124           1 :             const bool useChildren = is.read< bool >();
     125           1 :             if( useChildren && _mapNodeObjects( ))
     126             :             {
     127           0 :                 Pipes result;
     128           0 :                 is.deserializeChildren( this, _pipes, result );
     129           0 :                 _pipes.swap( result );
     130           0 :                 LBASSERT( _pipes.size() == result.size( ));
     131             :             }
     132             :             else // consume unused ObjectVersions
     133           1 :                 is.read< co::ObjectVersions >();
     134             :         }
     135             :     }
     136           3 :     if( dirtyBits & DIRTY_MEMBER )
     137           1 :         is >> _isAppNode;
     138           3 : }
     139             : 
     140             : template< class C, class N, class P, class V >
     141       62406 : void Node< C, N, P, V >::setDirty( const uint64_t dirtyBits )
     142             : {
     143       62406 :     Object::setDirty( dirtyBits );
     144       62406 :     _config->setDirty( C::DIRTY_NODES );
     145       62406 : }
     146             : 
     147             : template< class C, class N, class P, class V >
     148           5 : void Node< C, N, P, V >::notifyDetach()
     149             : {
     150           5 :     Object::notifyDetach();
     151          10 :     while( !_pipes.empty( ))
     152             :     {
     153           4 :         P* pipe = _pipes.back();
     154           4 :         if( !pipe->isAttached( ))
     155             :         {
     156           4 :             LBASSERT( isMaster( ));
     157           9 :             return;
     158             :         }
     159             : 
     160           0 :         LBASSERT( !isMaster( ));
     161           0 :         getLocalNode()->unmapObject( pipe );
     162           0 :         _removePipe( pipe );
     163           0 :         _config->getServer()->getNodeFactory()->releasePipe( pipe );
     164             :     }
     165             : }
     166             : 
     167             : template< class C, class N, class P, class V >
     168           0 : void Node< C, N, P, V >::create( P** pipe )
     169             : {
     170           0 :     *pipe = _config->getServer()->getNodeFactory()->createPipe(
     171             :         static_cast< N* >( this ));
     172           0 : }
     173             : 
     174             : template< class C, class N, class P, class V >
     175           0 : void Node< C, N, P, V >::release( P* pipe )
     176             : {
     177           0 :     _config->getServer()->getNodeFactory()->releasePipe( pipe );
     178           0 : }
     179             : 
     180             : namespace
     181             : {
     182             : template< class N, class V >
     183       20650 : VisitorResult _accept( N* node, V& visitor )
     184             : {
     185       20650 :     VisitorResult result = visitor.visitPre( node );
     186       20650 :     if( result != TRAVERSE_CONTINUE )
     187         408 :         return result;
     188             : 
     189       20242 :     const typename N::Pipes& pipes = node->getPipes();
     190      129690 :     for( typename N::Pipes::const_iterator i = pipes.begin();
     191       86460 :          i != pipes.end(); ++i )
     192             :     {
     193       28314 :         switch( (*i)->accept( visitor ))
     194             :         {
     195             :             case TRAVERSE_TERMINATE:
     196        5326 :                 return TRAVERSE_TERMINATE;
     197             : 
     198             :             case TRAVERSE_PRUNE:
     199          44 :                 result = TRAVERSE_PRUNE;
     200          44 :                 break;
     201             : 
     202             :             case TRAVERSE_CONTINUE:
     203             :             default:
     204       22944 :                 break;
     205             :         }
     206             :     }
     207             : 
     208       14916 :     switch( visitor.visitPost( node ))
     209             :     {
     210             :         case TRAVERSE_TERMINATE:
     211           0 :             return TRAVERSE_TERMINATE;
     212             : 
     213             :         case TRAVERSE_PRUNE:
     214           0 :             return TRAVERSE_PRUNE;
     215             : 
     216             :         case TRAVERSE_CONTINUE:
     217             :         default:
     218       14916 :             break;
     219             :     }
     220             : 
     221       14916 :     return result;
     222             : }
     223             : }
     224             : 
     225             : template< class C, class N, class P, class V >
     226       20650 : VisitorResult Node< C, N, P, V >::accept( V& visitor )
     227             : {
     228       20650 :     return _accept( static_cast< N* >( this ), visitor );
     229             : }
     230             : 
     231             : template< class C, class N, class P, class V >
     232           0 : VisitorResult Node< C, N, P, V >::accept( V& visitor ) const
     233             : {
     234           0 :     return _accept( static_cast< const N* >( this ), visitor );
     235             : }
     236             : 
     237             : template< class C, class N, class P, class V >
     238          92 : NodePath Node< C, N, P, V >::getPath() const
     239             : {
     240          92 :     const C* config = static_cast< const N* >( this )->getConfig( );
     241          92 :     LBASSERT( config );
     242             : 
     243          92 :     const typename std::vector< N* >& nodes = config->getNodes();
     244             :     typename std::vector< N* >::const_iterator i =
     245          92 :         std::find( nodes.begin(), nodes.end(), this );
     246          92 :     LBASSERT( i != nodes.end( ));
     247             : 
     248          92 :     NodePath path;
     249          92 :     path.nodeIndex = std::distance( nodes.begin(), i );
     250          92 :     return path;
     251             : }
     252             : 
     253             : template< class C, class N, class P, class V >
     254         426 : void Node< C, N, P, V >::setApplicationNode( const bool isAppNode )
     255             : {
     256         426 :     if( _isAppNode == isAppNode )
     257         426 :         return;
     258         426 :     _isAppNode = isAppNode;
     259         426 :     setDirty( DIRTY_MEMBER );
     260             : }
     261             : 
     262             : template< class C, class N, class P, class V > void
     263        2587 : Node< C, N, P, V >::setIAttribute( const IAttribute attr, const int32_t value )
     264             : {
     265        2587 :     if( _data.iAttributes[attr] == value )
     266        3449 :         return;
     267        1725 :     _data.iAttributes[attr] = value;
     268        1725 :     setDirty( DIRTY_ATTRIBUTES );
     269             : }
     270             : 
     271             : template< class C, class N, class P, class V >
     272        1298 : int32_t Node< C, N, P, V >::getIAttribute( const IAttribute attr ) const
     273             : {
     274        1298 :     return _data.iAttributes[attr];
     275             : }
     276             : 
     277             : template< class C, class N, class P, class V > const std::string&
     278        2044 : Node< C, N, P, V >::getIAttributeString( const IAttribute attr )
     279             : {
     280        2044 :     return _iAttributeStrings[attr];
     281             : }
     282             : 
     283             : template< class C, class N, class P, class V >
     284        1237 : void Node< C, N, P, V >::_addPipe( P* pipe )
     285             : {
     286        1237 :     LBASSERT( pipe->getNode() == this );
     287        1237 :     _pipes.push_back( pipe );
     288        1237 : }
     289             : 
     290             : template< class C, class N, class P, class V >
     291        2289 : bool Node< C, N, P, V >::_removePipe( P* pipe )
     292             : {
     293        2289 :     typename Pipes::iterator i = lunchbox::find( _pipes, pipe );
     294        2289 :     if( i == _pipes.end( ))
     295        1144 :         return false;
     296             : 
     297        1145 :     _pipes.erase( i );
     298        1145 :     return true;
     299             : }
     300             : 
     301             : template< class C, class N, class P, class V >
     302           1 : P* Node< C, N, P, V >::findPipe( const uint128_t& id )
     303             : {
     304           3 :     for( typename Pipes::const_iterator i = _pipes.begin();
     305           2 :          i != _pipes.end(); ++i )
     306             :     {
     307           1 :         P* pipe = *i;
     308           1 :         if( pipe->getID() == id )
     309           1 :             return pipe;
     310             :     }
     311           0 :     return 0;
     312             : }
     313             : 
     314             : template< class C, class N, class P, class V >
     315         432 : std::ostream& operator << ( std::ostream& os, const Node< C, N, P, V >& node )
     316             : {
     317         432 :     os << lunchbox::disableFlush << lunchbox::disableHeader;
     318         432 :     if( node.isApplicationNode( ))
     319         214 :         os << "appNode" << std::endl;
     320             :     else
     321         218 :         os << "node" << std::endl;
     322             : 
     323         432 :     os << "{" << std::endl << lunchbox::indent;
     324             : 
     325         432 :     const std::string& name = node.getName();
     326         432 :     if( !name.empty( ))
     327          18 :         os << "name     \"" << name << "\"" << std::endl;
     328             : 
     329         432 :     node.output( os );
     330             : 
     331         432 :     const typename N::Pipes& pipes = node.getPipes();
     332        3018 :     for( typename N::Pipes::const_iterator i = pipes.begin();
     333        2012 :          i != pipes.end(); ++i )
     334             :     {
     335         574 :         os << **i;
     336             :     }
     337         864 :     os << lunchbox::exdent << "}" << std::endl
     338         432 :        << lunchbox::enableHeader << lunchbox::enableFlush;
     339         432 :     return os;
     340             : }
     341             : 
     342             : }
     343             : }

Generated by: LCOV version 1.11