LCOV - code coverage report
Current view: top level - eq - init.cpp (source / functions) Hit Total Coverage
Test: Equalizer Lines: 100 173 57.8 %
Date: 2016-09-29 05:02:09 Functions: 7 9 77.8 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2005-2016, Stefan Eilemann <eile@equalizergraphics.com>
       3             :  *                          Cedric Stalder <cedric.stalder@gmail.com>
       4             :  *                          Daniel Nachbaur <danielnachbaur@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 "init.h"
      21             : 
      22             : #ifdef EQUALIZER_USE_QT5WIDGETS
      23             : #  include <QApplication>
      24             : #  include "qt/windowSystem.h"
      25             : #endif
      26             : 
      27             : #include "client.h"
      28             : #include "config.h"
      29             : #include "global.h"
      30             : #include "nodeFactory.h"
      31             : #include "os.h"
      32             : #include "server.h"
      33             : 
      34             : #include <eq/version.h>
      35             : #include <eq/fabric/configParams.h>
      36             : #include <eq/fabric/init.h>
      37             : #include <co/global.h>
      38             : #include <lunchbox/file.h>
      39             : #include <pression/pluginRegistry.h>
      40             : 
      41             : #ifdef _WIN32
      42             : #  pragma warning( push )
      43             : #  pragma warning( disable : 4275 4251 )
      44             : #endif
      45             : #include <boost/filesystem.hpp>
      46             : #include <boost/foreach.hpp>
      47             : #include <boost/program_options/options_description.hpp>
      48             : #include <boost/program_options/parsers.hpp>
      49             : #include <boost/program_options/variables_map.hpp>
      50             : #ifdef _WIN32
      51             : #  pragma warning( pop )
      52             : #endif
      53             : 
      54             : #include <fstream>
      55             : 
      56             : #ifdef _MSC_VER
      57             : #  define atoll _atoi64
      58             : #endif
      59             : #ifndef MAXPATHLEN
      60             : #  define MAXPATHLEN 1024
      61             : #endif
      62             : 
      63             : namespace arg = boost::program_options;
      64             : 
      65             : namespace eq
      66             : {
      67             : namespace
      68             : {
      69          14 : static lunchbox::a_int32_t _initialized;
      70          14 : static std::vector< WindowSystemIF* > _windowSystems;
      71             : }
      72             : 
      73             : const char EQ_HELP[] = "eq-help";
      74             : const char EQ_LOGFILE[] = "eq-logfile";
      75             : const char EQ_SERVER[] = "eq-server";
      76             : const char EQ_CLIENT[] = "eq-client";
      77             : const char EQ_CONFIG[] = "eq-config";
      78             : const char EQ_CONFIG_FLAGS[] = "eq-config-flags";
      79             : const char EQ_CONFIG_PREFIXES[] = "eq-config-prefixes";
      80             : const char EQ_RENDER_CLIENT[] = "eq-render-client";
      81             : 
      82             : static bool _parseArguments( const int argc, char** argv );
      83             : static void _initPlugins();
      84             : static void _exitPlugins();
      85             : 
      86           5 : bool _init( const int argc, char** argv, NodeFactory* nodeFactory )
      87             : {
      88           5 :     const char *env = getenv( "EQ_LOG_LEVEL" );
      89           5 :     if( env )
      90           0 :         lunchbox::Log::level = lunchbox::Log::getLogLevel( env );
      91             : 
      92           5 :     env = getenv( "EQ_LOG_TOPICS" );
      93           5 :     if( env )
      94           0 :         lunchbox::Log::topics |= atoll( env );
      95             : 
      96           5 :     lunchbox::Log::instance().setThreadName( "Main" );
      97             : 
      98           5 :     if( ++_initialized > 1 ) // not first
      99             :     {
     100           0 :         LBERROR << "Equalizer client library initialized more than once"
     101           0 :                 << std::endl;
     102           0 :         return true;
     103             :     }
     104             : 
     105           5 :     if( !_parseArguments( argc, argv ))
     106           0 :         return false;
     107          25 :     LBDEBUG << "Equalizer v" << Version::getString() << " initializing"
     108          20 :             << std::endl;
     109             : 
     110             : #ifdef AGL
     111             :     GetCurrentEventQueue();
     112             : #endif
     113             : #ifdef GLX
     114           5 :     ::XInitThreads();
     115             : #endif
     116             : 
     117             : #ifdef EQUALIZER_USE_QT5WIDGETS
     118           5 :     if( QApplication::instance( ))
     119           0 :         _windowSystems.push_back( new qt::WindowSystem );
     120             : #endif
     121             : 
     122           5 :     LBASSERT( nodeFactory );
     123           5 :     Global::_nodeFactory = nodeFactory;
     124             : 
     125           5 :     const std::string& programName = Global::getProgramName();
     126           5 :     if( programName.empty() && argc > 0 )
     127           3 :         Global::setProgramName( argv[0] );
     128             : 
     129           5 :     const std::string& workDir = Global::getWorkDir();
     130           5 :     if( workDir.empty( ))
     131           5 :         Global::setWorkDir( lunchbox::getWorkDir( ));
     132             : 
     133           5 :     _initPlugins();
     134           5 :     return fabric::init( argc, argv );
     135             : }
     136             : 
     137           5 : bool exit()
     138             : {
     139           5 :     if( _initialized <= 0 )
     140             :     {
     141           0 :         LBERROR << "Equalizer client library not initialized" << std::endl;
     142           0 :         return false;
     143             :     }
     144           5 :     if( --_initialized > 0 ) // not last
     145           0 :         return true;
     146             : 
     147           5 :     BOOST_FOREACH( WindowSystemIF* windowSystem, _windowSystems )
     148           0 :         delete windowSystem;
     149           5 :     _windowSystems.clear();
     150             : 
     151           5 :     Global::_nodeFactory = 0;
     152           5 :     _exitPlugins();
     153           5 :     return fabric::exit();
     154             : }
     155             : 
     156           5 : bool _parseArguments( const int argc, char** argv )
     157             : {
     158             :     typedef stde::hash_map< std::string, uint32_t > Flags;
     159           5 :     Flags configFlags;
     160           5 :     configFlags["multiprocess"] = fabric::ConfigParams::FLAG_MULTIPROCESS;
     161           5 :     configFlags["multiprocess_db"] = fabric::ConfigParams::FLAG_MULTIPROCESS_DB;
     162           5 :     configFlags["ethernet"] = fabric::ConfigParams::FLAG_NETWORK_ETHERNET;
     163           5 :     configFlags["infiniband"] = fabric::ConfigParams::FLAG_NETWORK_INFINIBAND;
     164          10 :     configFlags["2D_horizontal"] =
     165           5 :         fabric::ConfigParams::FLAG_LOAD_EQ_HORIZONTAL;
     166          10 :     configFlags["2D_vertical"] =
     167           5 :         fabric::ConfigParams::FLAG_LOAD_EQ_VERTICAL;
     168          10 :     configFlags["2D_tiles"] =
     169           5 :         fabric::ConfigParams::FLAG_LOAD_EQ_2D;
     170             : 
     171          10 :     arg::options_description options( "Equalizer library options" );
     172             :     options.add_options()
     173          10 :         ( EQ_HELP, "Display usage information and exit" )
     174           5 :         ( EQ_LOGFILE, arg::value< std::string >(),
     175           5 :           "Redirect log output to given file" )
     176          10 :         ( EQ_SERVER, arg::value< std::string >(), "The server address" )
     177           5 :         ( EQ_CONFIG, arg::value< std::string >(),
     178           5 :           "Configuration filename or autoconfig session name" )
     179           5 :         ( EQ_CONFIG_FLAGS, arg::value< Strings >()->multitoken(),
     180           5 :           "Autoconfiguration flags" )
     181           5 :         ( EQ_CONFIG_PREFIXES, arg::value< Strings >()->multitoken(),
     182             :           "The network prefix filter(s) in CIDR notation for autoconfig "
     183           5 :           "(white-space separated)" )
     184           5 :         ( EQ_RENDER_CLIENT, arg::value< std::string >(),
     185             :           "The render client executable filename" )
     186           5 :     ;
     187             : 
     188          10 :     arg::variables_map vm;
     189             :     try
     190             :     {
     191           5 :         Strings args;
     192           8 :         for( int i = 0; i < argc; ++i )
     193             :         {
     194           3 :             if( strcmp( argv[i], "--" ) != 0 )
     195           3 :                 args.push_back( argv[i] );
     196             :         }
     197             :         arg::store( arg::command_line_parser( args )
     198           5 :                         .options( options ).allow_unregistered().run(), vm );
     199           5 :         arg::notify( vm );
     200             :     }
     201           0 :     catch( const std::exception& e )
     202             :     {
     203           0 :         LBERROR << "Error in argument parsing: " << e.what() << std::endl;
     204           0 :         return false;
     205             :     }
     206             : 
     207           5 :     if( vm.count( EQ_HELP ))
     208             :     {
     209           0 :         std::cout << options << std::endl;
     210           0 :         return false;
     211             :     }
     212             : 
     213           5 :     if( vm.count( EQ_SERVER ))
     214           0 :         Global::setServer( vm[EQ_SERVER].as< std::string >( ));
     215             : 
     216           5 :     if( vm.count( EQ_CONFIG ))
     217           0 :         Global::setConfig( vm[EQ_CONFIG].as< std::string >( ));
     218             : 
     219           5 :     if( vm.count( EQ_CONFIG_FLAGS ))
     220             :     {
     221           0 :         const Strings& flagStrings = vm[EQ_CONFIG_FLAGS].as< Strings >( );
     222           0 :         uint32_t flags = Global::getFlags();
     223           0 :         for( StringsCIter i = flagStrings.begin(); i != flagStrings.end(); ++i )
     224             :         {
     225           0 :             Flags::const_iterator j = configFlags.find( *i );
     226           0 :             if( j != configFlags.end( ))
     227           0 :                 flags |= j->second;
     228             :             else
     229           0 :                 LBWARN << "Unknown argument for --eq-config-flags: " << *i
     230           0 :                        << std::endl;
     231             :         }
     232           0 :         Global::setFlags( flags );
     233             :     }
     234             : 
     235           5 :     if( vm.count( EQ_CONFIG_PREFIXES ))
     236             :     {
     237           0 :         const Strings& prefixes = vm[EQ_CONFIG_PREFIXES].as< Strings >( );
     238           0 :         Global::setPrefixes( prefixes );
     239             :     }
     240             : 
     241           5 :     if( vm.count( EQ_CLIENT ))
     242             :     {
     243           0 :         const std::string& renderClient = vm[EQ_CLIENT].as< std::string >();
     244           0 :         const boost::filesystem::path path( renderClient );
     245             : 
     246           0 :         Global::setProgramName( renderClient );
     247           0 :         Global::setWorkDir( path.parent_path().string( ));
     248             :     }
     249             : 
     250           5 :     for( int i = 1; i < argc; ++i )
     251             :     {
     252           0 :         if( std::string( argv[i] ) == "--eq-logfile" )
     253             :         {
     254           0 :             argv[i][2] = 'l'; // rewrite to --lb-logfile
     255           0 :             argv[i][3] = 'b';
     256             :         }
     257             :     }
     258             : 
     259          10 :     return true;
     260             : }
     261             : 
     262           5 : void _initPlugins()
     263             : {
     264           5 :     pression::PluginRegistry& plugins = co::Global::getPluginRegistry();
     265             : 
     266          10 :     plugins.addDirectory( lunchbox::getRootPath() +
     267           5 :                           "/share/Equalizer/plugins" ); // install dir
     268           5 :     plugins.addDirectory( "/usr/share/Equalizer/plugins" );
     269           5 :     plugins.addDirectory( "/usr/local/share/Equalizer/plugins" );
     270           5 :     plugins.addDirectory( ".eqPlugins" );
     271           5 :     plugins.addDirectory( "/opt/local/lib" ); // MacPorts
     272           5 :     plugins.addDirectory( "/usr/local/lib" ); // Homebrew
     273             : 
     274           5 :     const char* home = getenv( "HOME" );
     275           5 :     if( home )
     276           5 :         plugins.addDirectory( std::string( home ) + "/.eqPlugins" );
     277             : 
     278             : #ifdef EQUALIZER_DSO_NAME
     279           5 :     if( plugins.addPlugin( EQUALIZER_DSO_NAME )) // Found by LDD
     280          10 :         return;
     281             : 
     282             :     // Hard-coded compile locations as backup:
     283           0 :     std::string absDSO = std::string( EQ_BUILD_DIR ) + "lib/" +
     284           0 :                          EQUALIZER_DSO_NAME;
     285           0 :     if( plugins.addPlugin( absDSO ))
     286           0 :         return;
     287             : 
     288             : #  ifdef NDEBUG
     289             :     absDSO = std::string( EQ_BUILD_DIR ) + "lib/Release/" + EQUALIZER_DSO_NAME;
     290             : #  else
     291           0 :     absDSO = std::string( EQ_BUILD_DIR ) + "lib/Debug/" + EQUALIZER_DSO_NAME;
     292             : #  endif
     293             : 
     294           0 :     if( plugins.addPlugin( absDSO ))
     295           0 :         return;
     296             : 
     297           0 :     LBWARN << "Built-in Equalizer plugins not loaded: " << EQUALIZER_DSO_NAME
     298           0 :            << " not in library search path and " << absDSO << " not found"
     299           0 :            << std::endl;
     300             : #else
     301             : #  ifndef NDEBUG
     302             : #    error "EQUALIZER_DSO_NAME not defined"
     303             : #  endif
     304             :     LBWARN << "Built-in Equalizer plugins not loaded: EQUALIZER_DSO_NAME not "
     305             :            << "defined" << std::endl;
     306             : #endif
     307             : }
     308             : 
     309           5 : void _exitPlugins()
     310             : {
     311           5 :     pression::PluginRegistry& plugins = co::Global::getPluginRegistry();
     312             : 
     313          10 :     plugins.removeDirectory( lunchbox::getRootPath() +
     314           5 :                              "/share/Equalizer/plugins" );
     315           5 :     plugins.removeDirectory( "/usr/share/Equalizer/plugins" );
     316           5 :     plugins.removeDirectory( "/usr/local/share/Equalizer/plugins" );
     317           5 :     plugins.removeDirectory( ".eqPlugins" );
     318           5 :     plugins.removeDirectory( "/opt/local/lib" ); // MacPorts
     319           5 :     plugins.removeDirectory( "/usr/local/lib" ); // Homebrew
     320             : 
     321           5 :     const char* home = getenv( "HOME" );
     322           5 :     if( home )
     323           5 :         plugins.removeDirectory( std::string( home ) + "/.eqPlugins" );
     324           5 : }
     325             : 
     326           0 : Config* getConfig( const int argc, char** argv )
     327             : {
     328             :     // 1. initialization of a local client node
     329           0 :     ClientPtr client = new Client;
     330           0 :     if( client->initLocal( argc, argv ))
     331             :     {
     332             :         // 2. connect to server
     333           0 :         ServerPtr server = new Server;
     334           0 :         if( client->connectServer( server ))
     335             :         {
     336             :             // 3. choose configuration
     337           0 :             fabric::ConfigParams configParams;
     338           0 :             Config* config = server->chooseConfig( configParams );
     339           0 :             if( config )
     340           0 :                 return config;
     341             : 
     342           0 :             LBERROR << "No matching config on server" << std::endl;
     343             : 
     344             :             // -2. disconnect server
     345           0 :             client->disconnectServer( server );
     346             :         }
     347             :         else
     348           0 :             LBERROR << "Can't open server" << std::endl;
     349             : 
     350             :         // -1. exit local client node
     351           0 :         client->exitLocal();
     352             :     }
     353             :     else
     354           0 :         LBERROR << "Can't init local client node" << std::endl;
     355             : 
     356           0 :     return 0;
     357             : }
     358             : 
     359           0 : void releaseConfig( Config* config )
     360             : {
     361           0 :     if( !config )
     362           0 :         return;
     363             : 
     364           0 :     ServerPtr server = config->getServer();
     365           0 :     LBASSERT( server.isValid( ));
     366           0 :     server->releaseConfig( config );
     367             : 
     368           0 :     ClientPtr client = server->getClient();
     369           0 :     LBASSERT( client.isValid( ));
     370             : 
     371           0 :     client->disconnectServer( server );
     372           0 :     client->exitLocal();
     373             : 
     374           0 :     LBASSERTINFO( client->getRefCount() == 1, client->getRefCount( ));
     375           0 :     LBASSERTINFO( server->getRefCount() == 1, server->getRefCount( ));
     376             : }
     377             : 
     378          42 : }

Generated by: LCOV version 1.11