FairMQ  1.2.1
C++ Message Passing Framework
PluginManager.h
1 /********************************************************************************
2  * Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
3  * *
4  * This software is distributed under the terms of the *
5  * GNU Lesser General Public Licence (LGPL) version 3, *
6  * copied verbatim in the file "LICENSE" *
7  ********************************************************************************/
8 
9 #ifndef FAIR_MQ_PLUGINMANAGER_H
10 #define FAIR_MQ_PLUGINMANAGER_H
11 
12 #include <fairmq/Plugin.h>
13 #include <fairmq/PluginServices.h>
14 #include <fairmq/plugins/Builtin.h>
15 #include <fairmq/Tools.h>
16 #include <FairMQDevice.h>
17 #define BOOST_FILESYSTEM_VERSION 3
18 #define BOOST_FILESYSTEM_NO_DEPRECATED
19 #include <boost/filesystem.hpp>
20 #include <boost/optional.hpp>
21 #include <boost/program_options.hpp>
22 #include <boost/dll/import.hpp>
23 #include <boost/dll/shared_library.hpp>
24 #include <boost/dll/runtime_symbol_info.hpp>
25 #include <functional>
26 #include <map>
27 #include <memory>
28 #include <stdexcept>
29 #include <string>
30 #include <tuple>
31 #include <vector>
32 
33 namespace fair
34 {
35 namespace mq
36 {
37 
49 {
50  public:
51  using PluginFactory = std::shared_ptr<fair::mq::Plugin>(PluginServices&);
52 
53  PluginManager();
54 
55  auto SetSearchPaths(const std::vector<boost::filesystem::path>&) -> void;
56  auto AppendSearchPath(const boost::filesystem::path&) -> void;
57  auto PrependSearchPath(const boost::filesystem::path&) -> void;
58  auto SearchPaths() const -> const std::vector<boost::filesystem::path>& { return fSearchPaths; }
59  struct BadSearchPath : std::invalid_argument { using std::invalid_argument::invalid_argument; };
60 
61  auto LoadPlugin(const std::string& pluginName) -> void;
62  auto LoadPlugins(const std::vector<std::string>& pluginNames) -> void { for(const auto& pluginName : pluginNames) { LoadPlugin(pluginName); } }
63  struct PluginLoadError : std::runtime_error { using std::runtime_error::runtime_error; };
64  auto InstantiatePlugins() -> void;
65  struct PluginInstantiationError : std::runtime_error { using std::runtime_error::runtime_error; };
66 
67  static auto ProgramOptions() -> boost::program_options::options_description;
68  static auto MakeFromCommandLineOptions(const std::vector<std::string>) -> std::shared_ptr<PluginManager>;
69  struct ProgramOptionsParseError : std::runtime_error { using std::runtime_error::runtime_error; };
70 
71  static auto LibPrefix() -> const std::string& { return fgkLibPrefix; }
72 
73  auto ForEachPlugin(std::function<void (Plugin&)> func) -> void { for(const auto& p : fPluginOrder) { func(*fPlugins[p]); } }
74  auto ForEachPluginProgOptions(std::function<void (boost::program_options::options_description)> func) const -> void { for(const auto& pair : fPluginProgOptions) { func(pair.second); } }
75 
76  template<typename... Args>
77  auto EmplacePluginServices(Args&&... args) -> void { fPluginServices = fair::mq::tools::make_unique<PluginServices>(std::forward<Args>(args)...); };
78 
79  auto WaitForPluginsToReleaseDeviceControl() -> void { fPluginServices->WaitForReleaseDeviceControl(); }
80 
81  private:
82  static auto ValidateSearchPath(const boost::filesystem::path&) -> void;
83 
84  auto LoadPluginPrelinkedDynamic(const std::string& pluginName) -> void;
85  auto LoadPluginDynamic(const std::string& pluginName) -> void;
86  auto LoadPluginStatic(const std::string& pluginName) -> void;
87  template<typename... Args>
88  auto LoadSymbols(const std::string& pluginName, Args&&... args) -> void
89  {
90  using namespace boost::dll;
91  using fair::mq::tools::ToString;
92 
93  auto lib = shared_library{std::forward<Args>(args)...};
94 
95  fPluginFactories[pluginName] = import_alias<PluginFactory>(
96  shared_library{lib},
97  ToString("make_", pluginName, "_plugin")
98  );
99 
100  try
101  {
102  fPluginProgOptions.insert({
103  pluginName,
104  lib.get_alias<Plugin::ProgOptions()>(ToString("get_", pluginName, "_plugin_progoptions"))().value()
105  });
106  }
107  catch (const boost::bad_optional_access& e) { /* just ignore, if no prog options are declared */ }
108  }
109 
110  auto InstantiatePlugin(const std::string& pluginName) -> void;
111 
112  static const std::string fgkLibPrefix;
113  std::vector<boost::filesystem::path> fSearchPaths;
114  std::map<std::string, std::function<PluginFactory>> fPluginFactories;
115  std::map<std::string, std::shared_ptr<Plugin>> fPlugins;
116  std::vector<std::string> fPluginOrder;
117  std::map<std::string, boost::program_options::options_description> fPluginProgOptions;
118  std::unique_ptr<PluginServices> fPluginServices;
119 }; /* class PluginManager */
120 
121 } /* namespace mq */
122 } /* namespace fair */
123 
124 #endif /* FAIR_MQ_PLUGINMANAGER_H */
Facilitates communication between devices and plugins.
Definition: PluginServices.h:37
Definition: PluginManager.h:59
manages and owns plugin instances
Definition: PluginManager.h:48
Base class for FairMQ plugins.
Definition: Plugin.h:38
Definition: PluginManager.h:63
Definition: DeviceRunner.h:23