LCOV - code coverage report
Current view: top level - eq/fabric - server.ipp (source / functions) Hit Total Coverage
Test: lcov2.info Lines: 88 101 87.1 %
Date: 2014-06-18 Functions: 16 26 61.5 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2010-2013, Stefan Eilemann <eile@eyescale.ch>
       3             :  *                    2012, Daniel Nachbaur <danielnachbaur@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 "server.h"
      20             : 
      21             : #include "configVisitor.h"
      22             : #include "elementVisitor.h"
      23             : #include "leafVisitor.h"
      24             : #include "log.h"
      25             : 
      26             : #include <co/iCommand.h>
      27             : #include <co/connectionDescription.h>
      28             : #include <co/global.h>
      29             : 
      30             : namespace eq
      31             : {
      32             : namespace fabric
      33             : {
      34             : 
      35             : #define CmdFunc co::CommandFunc< Server< CL, S, CFG, NF, N, V > >
      36             : 
      37             : template< class CL, class S, class CFG, class NF, class N, class V >
      38         237 : Server< CL, S, CFG, NF, N, V >::Server( NF* nodeFactory )
      39             :         : N( NODETYPE_SERVER )
      40         237 :         , _nodeFactory( nodeFactory )
      41             : {
      42         237 :     LBASSERT( nodeFactory );
      43         237 :     LBLOG( LOG_INIT ) << "New " << lunchbox::className( this ) << std::endl;
      44         237 : }
      45             : 
      46             : template< class CL, class S, class CFG, class NF, class N, class V >
      47         226 : Server< CL, S, CFG, NF, N, V >::~Server()
      48             : {
      49         226 :     LBLOG( LOG_INIT ) << "Delete " << lunchbox::className( this ) << std::endl;
      50         226 :     _client = 0;
      51         226 :     LBASSERT( _configs.empty( ));
      52         452 : }
      53             : 
      54             : template< class CL, class S, class CFG, class NF, class N, class V >
      55          32 : void Server< CL, S, CFG, NF, N, V >::setClient( ClientPtr client )
      56             : {
      57          32 :     _client = client;
      58          32 :     if( !client )
      59          48 :         return;
      60             : 
      61          16 :     co::CommandQueue* queue = static_cast< S* >( this )->getMainThreadQueue();
      62          16 :     this->registerCommand( CMD_SERVER_CREATE_CONFIG,
      63             :                      CmdFunc( this, &Server::_cmdCreateConfig ), queue );
      64          16 :     this->registerCommand( CMD_SERVER_DESTROY_CONFIG,
      65             :                      CmdFunc( this, &Server::_cmdDestroyConfig ), queue );
      66             : }
      67             : 
      68             : template< class CL, class S, class CFG, class NF, class N, class V >
      69         235 : void Server< CL, S, CFG, NF, N, V >::_addConfig( CFG* config )
      70             : {
      71         235 :     LBASSERT( config->getServer() == static_cast< S* >( this ));
      72         235 :     LBASSERT( lunchbox::find( _configs, config ) == _configs.end( ));
      73         235 :     _configs.push_back( config );
      74         235 : }
      75             : 
      76             : template< class CL, class S, class CFG, class NF, class N, class V >
      77         430 : bool Server< CL, S, CFG, NF, N, V >::_removeConfig( CFG* config )
      78             : {
      79         430 :     typename Configs::iterator i = lunchbox::find( _configs, config );
      80         430 :     if( i == _configs.end( ))
      81         206 :         return false;
      82             : 
      83         224 :     _configs.erase( i );
      84         224 :     return true;
      85             : }
      86             : 
      87             : namespace
      88             : {
      89             : template< class S, class V >
      90         488 : VisitorResult _accept( S* server, V& visitor )
      91             : {
      92         488 :     VisitorResult result = visitor.visitPre( server );
      93         488 :     if( result != TRAVERSE_CONTINUE )
      94           0 :         return result;
      95             : 
      96         488 :     const typename S::Configs& configs = server->getConfigs();
      97        2742 :     for( typename S::Configs::const_iterator i = configs.begin();
      98        1828 :          i != configs.end(); ++i )
      99             :     {
     100         426 :         switch( (*i)->accept( visitor ))
     101             :         {
     102             :             case TRAVERSE_TERMINATE:
     103           0 :                 return TRAVERSE_TERMINATE;
     104             : 
     105             :             case TRAVERSE_PRUNE:
     106         410 :                 result = TRAVERSE_PRUNE;
     107         410 :                 break;
     108             : 
     109             :             case TRAVERSE_CONTINUE:
     110             :             default:
     111          16 :                 break;
     112             :         }
     113             :     }
     114             : 
     115         488 :     switch( visitor.visitPost( server ))
     116             :     {
     117             :         case TRAVERSE_TERMINATE:
     118           0 :             return TRAVERSE_TERMINATE;
     119             : 
     120             :         case TRAVERSE_PRUNE:
     121           0 :             return TRAVERSE_PRUNE;
     122             : 
     123             :         case TRAVERSE_CONTINUE:
     124             :         default:
     125         488 :             break;
     126             :     }
     127             : 
     128         488 :     return result;
     129             : }
     130             : }
     131             : 
     132             : template< class CL, class S, class CFG, class NF, class N, class V >
     133         488 : VisitorResult Server< CL, S, CFG, NF, N, V >::accept( V& visitor )
     134             : {
     135         488 :     return _accept( static_cast< S* >( this ), visitor );
     136             : }
     137             : 
     138             : template< class CL, class S, class CFG, class NF, class N, class V >
     139           0 : VisitorResult Server< CL, S, CFG, NF, N, V >::accept( V& visitor ) const
     140             : {
     141           0 :     return _accept( static_cast< const S* >( this ), visitor );
     142             : }
     143             : 
     144             : //---------------------------------------------------------------------------
     145             : // command handlers
     146             : //---------------------------------------------------------------------------
     147             : template< class CL, class S, class CFG, class NF, class N, class V > bool
     148          10 : Server< CL, S, CFG, NF, N, V >::_cmdCreateConfig( co::ICommand& command )
     149             : {
     150          10 :     const co::ObjectVersion& configVersion = command.read< co::ObjectVersion >();
     151          10 :     const uint32_t requestID = command.read< uint32_t >();
     152             : 
     153          10 :     LBVERB << "Handle create config " << command << " config version "
     154           0 :            << configVersion << " request " << requestID << std::endl;
     155             : 
     156          10 :     CFG* config = _nodeFactory->createConfig( static_cast< S* >( this ));
     157          10 :     co::LocalNodePtr localNode = command.getLocalNode();
     158          10 :     if( !localNode->mapObject( config, configVersion ))
     159             :     {
     160           0 :         LBUNREACHABLE;
     161           0 :         LBERROR << "Can't map chosen config" << std::endl;
     162             : 
     163           0 :         _nodeFactory->releaseConfig( config );
     164           0 :         return true;
     165             :     }
     166             : 
     167          10 :     co::Global::setIAttribute( co::Global::IATTR_ROBUSTNESS,
     168          10 :                                config->getIAttribute( CFG::IATTR_ROBUSTNESS ));
     169          10 :     if( requestID != LB_UNDEFINED_UINT32 )
     170           0 :         config->send( command.getRemoteNode(), CMD_CONFIG_CREATE_REPLY )
     171           0 :                 << requestID;
     172             : 
     173          10 :     return true;
     174             : }
     175             : 
     176             : template< class CL, class S, class CFG, class NF, class N, class V > bool
     177          10 : Server< CL, S, CFG, NF, N, V >::_cmdDestroyConfig( co::ICommand& command )
     178             : {
     179          10 :     LBVERB << "Handle destroy config " << command << std::endl;
     180             : 
     181          10 :     co::LocalNodePtr localNode = command.getLocalNode();
     182          10 :     const uint128_t& configID = command.read< uint128_t >();
     183          10 :     const uint32_t requestID = command.read< uint32_t >();
     184             : 
     185          10 :     CFG* config = 0;
     186          30 :     for( typename Configs::const_iterator i = _configs.begin();
     187          20 :          i != _configs.end(); ++i )
     188             :     {
     189          10 :         if( (*i)->getID() ==  configID )
     190             :         {
     191          10 :             config = *i;
     192          10 :             break;
     193             :         }
     194             :     }
     195          10 :     LBASSERT( config );
     196             : 
     197          10 :     localNode->unmapObject( config );
     198          10 :     _nodeFactory->releaseConfig( config );
     199             : 
     200          10 :     if( requestID != LB_UNDEFINED_UINT32 )
     201          20 :         command.getRemoteNode()->send( CMD_SERVER_DESTROY_CONFIG_REPLY )
     202          20 :                 << requestID;
     203             : 
     204          10 :     return true;
     205             : }
     206             : 
     207             : template< class CL, class S, class CFG, class NF, class N, class V >
     208         134 : std::ostream& operator << ( std::ostream& os,
     209             :                             const Server< CL, S, CFG, NF, N, V >& server )
     210             : {
     211         134 :     os << lunchbox::disableFlush << lunchbox::disableHeader << "server "
     212             :        << std::endl;
     213         134 :     os << "{" << std::endl << lunchbox::indent;
     214             : 
     215             :     const co::ConnectionDescriptions& cds =
     216         134 :         server.getConnectionDescriptions();
     217         729 :     for( co::ConnectionDescriptions::const_iterator i = cds.begin();
     218         486 :          i != cds.end(); ++i )
     219             :     {
     220         109 :         co::ConnectionDescriptionPtr desc = *i;
     221         109 :         os << *desc;
     222             :     }
     223             : 
     224         134 :     const std::vector< CFG* >& configs = server.getConfigs();
     225         762 :     for( typename std::vector< CFG* >::const_iterator i = configs.begin();
     226         508 :          i != configs.end(); ++i )
     227             :     {
     228         120 :         const CFG* config = *i;
     229         120 :         os << *config;
     230             :     }
     231             : 
     232         268 :     os << lunchbox::exdent << "}"  << lunchbox::enableHeader
     233         134 :        << lunchbox::enableFlush << std::endl;
     234             : 
     235         134 :     return os;
     236             : }
     237             : 
     238             : }
     239             : }

Generated by: LCOV version 1.10