LCOV - code coverage report
Current view: top level - eq/fabric - server.ipp (source / functions) Hit Total Coverage
Test: Equalizer Lines: 87 100 87.0 %
Date: 2017-12-16 05:07:20 Functions: 16 39 41.0 %

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

Generated by: LCOV version 1.11