LCOV - code coverage report
Current view: top level - lunchbox - pluginFactory.ipp (source / functions) Hit Total Coverage
Test: Lunchbox Lines: 18 19 94.7 %
Date: 2016-11-11 05:21:33 Functions: 5 5 100.0 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2013-2016, EPFL/Blue Brain Project
       3             :  *                          Raphael Dumusc <raphael.dumusc@epfl.ch>
       4             :  *                          Stefan.Eilemann@epfl.ch
       5             :  *
       6             :  * This file is part of Lunchbox <https://github.com/Eyescale/Lunchbox>
       7             :  *
       8             :  * This library is free software; you can redistribute it and/or modify it under
       9             :  * the terms of the GNU Lesser General Public License version 2.1 as published
      10             :  * by the Free Software Foundation.
      11             :  *
      12             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      13             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      14             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      15             :  * details.
      16             :  *
      17             :  * You should have received a copy of the GNU Lesser General Public License
      18             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      19             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      20             :  */
      21             : 
      22             : namespace lunchbox
      23             : {
      24          12 : template< typename T > PluginFactory< T >& PluginFactory< T >::getInstance()
      25             : {
      26          12 :     static PluginFactory< T > factory;
      27          12 :     return factory;
      28             : }
      29             : 
      30           1 : template< typename T > PluginFactory< T >::~PluginFactory()
      31             : {
      32             :     // Do not do this: dtor is called in atexit(), at which point the other DSOs
      33             :     // might be unloaded already, causing dlclose to trip. It's pointless
      34             :     // anyways, we're in atexit, so the OS will dispose the DSOs for us anyways.
      35             :     // Let's call this a static deinitializer fiasco.
      36             :     //   deregisterAll(); // unload the DSO libraries
      37           1 : }
      38             : 
      39             : template< typename T >
      40           4 : T* PluginFactory< T >::create( const typename T::InitDataT& initData )
      41             : {
      42           6 :     for( auto& plugin : _plugins )
      43           4 :         if( plugin.handles( initData ))
      44           4 :             return plugin.construct( initData );
      45             : 
      46           2 :     LBTHROW( std::runtime_error( "No plugin implementation available for " +
      47             :                                  std::to_string( initData )));
      48             : }
      49             : 
      50             : template< typename T >
      51           4 : void PluginFactory< T >::register_( const PluginT& plugin )
      52             : {
      53           4 :     _plugins.push_back( plugin );
      54           4 : }
      55             : 
      56             : template< typename T >
      57             : bool PluginFactory< T >::deregister( const PluginT& plugin )
      58             : {
      59             :     typename Plugins::iterator i = std::find( _plugins.begin(), _plugins.end(),
      60             :                                               plugin );
      61             :     if( i == _plugins.end( ))
      62             :         return false;
      63             : 
      64             :     _plugins.erase( i );
      65             :     return true;
      66             : }
      67             : 
      68           4 : template< typename T > void PluginFactory< T >::deregisterAll()
      69             : {
      70           4 :     _plugins.clear();
      71           4 :     for( auto& plugin : _libraries )
      72           0 :         delete plugin.first;
      73           4 :     _libraries.clear();
      74           4 : }
      75             : 
      76             : template< typename T >
      77             : void PluginFactory< T >::load( const int version, const Strings& paths,
      78             :                                const std::string& pattern )
      79             : {
      80             :     Strings unique = paths;
      81             :     lunchbox::usort( unique );
      82             : 
      83             :     for( const auto& path : unique )
      84             :         load( version, path, pattern );
      85             : }
      86             : 
      87             : template< typename T >
      88             : void PluginFactory< T >::load( const int version, const std::string& path,
      89             :                                const std::string& pattern )
      90             : {
      91             : #ifdef _MSC_VER
      92             :     const std::string regex( pattern + ".dll" );
      93             : #elif __APPLE__
      94             :     const std::string regex( "lib" + pattern + ".dylib" );
      95             : #else
      96             :     const std::string regex( "lib" + pattern + ".so" );
      97             : #endif
      98             :     const Strings& libs = searchDirectory( path, regex );
      99             : 
     100             :     for( const auto& lib : libs )
     101             :     {
     102             :         lunchbox::DSO* dso = new lunchbox::DSO( path + "/" + lib );
     103             :         if( !dso->isOpen())
     104             :         {
     105             :             delete dso;
     106             :             continue;
     107             :         }
     108             : 
     109             :         typedef int( *GetVersion_t )();
     110             :         typedef bool( *Register_t )();
     111             : 
     112             :         GetVersion_t getVersion = dso->getFunctionPointer< GetVersion_t >(
     113             :             "LunchboxPluginGetVersion" );
     114             :         Register_t registerFunc = dso->getFunctionPointer< Register_t >(
     115             :             "LunchboxPluginRegister" );
     116             :         const bool matchesVersion = getVersion && (getVersion() == version);
     117             : 
     118             :         if( !getVersion || !registerFunc || !matchesVersion )
     119             :         {
     120             :             LBERROR << "Disable " << lib << ": "
     121             :                     << ( getVersion ? "" :
     122             :                         "Symbol for LunchboxPluginGetVersion missing " )
     123             :                     << ( registerFunc ? "" :
     124             :                         "Symbol for LunchboxPluginRegister missing " );
     125             :             if( getVersion && !matchesVersion )
     126             :                 LBERROR << "Plugin version " << getVersion() << " does not"
     127             :                         << " match application version " << version;
     128             :             LBERROR << std::endl;
     129             : 
     130             :             delete dso;
     131             :             continue;
     132             :         }
     133             : 
     134             :         if( registerFunc( ))
     135             :         {
     136             :             _libraries.insert( std::make_pair( dso, _plugins.back( )));
     137             :             LBINFO << "Enabled plugin " << lib << std::endl;
     138             :         }
     139             :         else
     140             :             delete dso;
     141             :     }
     142             : }
     143             : }

Generated by: LCOV version 1.11