LCOV - code coverage report
Current view: top level - eq - init.cpp (source / functions) Hit Total Coverage
Test: Equalizer Lines: 92 158 58.2 %
Date: 2017-12-16 05:07:20 Functions: 8 11 72.7 %

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

Generated by: LCOV version 1.11