FairMQ  1.4.14
C++ Message Queuing Library and 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/tools/CppSTL.h>
15 #include <fairmq/tools/Strings.h>
16 
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 
26 #include <functional>
27 #include <map>
28 #include <memory>
29 #include <stdexcept>
30 #include <string>
31 #include <vector>
32 #include <utility> // forward
33 
34 namespace fair
35 {
36 namespace mq
37 {
38 
50 {
51  public:
52  using PluginFactory = std::unique_ptr<fair::mq::Plugin>(PluginServices&);
53 
54  PluginManager();
55  PluginManager(const std::vector<std::string> args);
56 
57  ~PluginManager()
58  {
59  LOG(debug) << "Shutting down Plugin Manager";
60  }
61 
62  auto SetSearchPaths(const std::vector<boost::filesystem::path>&) -> void;
63  auto AppendSearchPath(const boost::filesystem::path&) -> void;
64  auto PrependSearchPath(const boost::filesystem::path&) -> void;
65  auto SearchPaths() const -> const std::vector<boost::filesystem::path>& { return fSearchPaths; }
66  struct BadSearchPath : std::invalid_argument { using std::invalid_argument::invalid_argument; };
67 
68  auto LoadPlugin(const std::string& pluginName) -> void;
69  auto LoadPlugins(const std::vector<std::string>& pluginNames) -> void { for(const auto& pluginName : pluginNames) { LoadPlugin(pluginName); } }
70  struct PluginLoadError : std::runtime_error { using std::runtime_error::runtime_error; };
71  auto InstantiatePlugins() -> void;
72  struct PluginInstantiationError : std::runtime_error { using std::runtime_error::runtime_error; };
73 
74  static auto ProgramOptions() -> boost::program_options::options_description;
75  struct ProgramOptionsParseError : std::runtime_error { using std::runtime_error::runtime_error; };
76 
77  static auto LibPrefix() -> const std::string& { return fgkLibPrefix; }
78 
79  auto ForEachPlugin(std::function<void (Plugin&)> func) -> void { for(const auto& p : fPluginOrder) { func(*fPlugins[p]); } }
80  auto ForEachPluginProgOptions(std::function<void (boost::program_options::options_description)> func) const -> void { for(const auto& pair : fPluginProgOptions) { func(pair.second); } }
81 
82  template<typename... Args>
83  auto EmplacePluginServices(Args&&... args) -> void { fPluginServices = fair::mq::tools::make_unique<PluginServices>(std::forward<Args>(args)...); }
84 
85  auto WaitForPluginsToReleaseDeviceControl() -> void { fPluginServices->WaitForReleaseDeviceControl(); }
86 
87  private:
88  static auto ValidateSearchPath(const boost::filesystem::path&) -> void;
89 
90  auto LoadPluginPrelinkedDynamic(const std::string& pluginName) -> void;
91  auto LoadPluginDynamic(const std::string& pluginName) -> void;
92  auto LoadPluginStatic(const std::string& pluginName) -> void;
93  template<typename... Args>
94  auto LoadSymbols(const std::string& pluginName, Args&&... args) -> void
95  {
96  using namespace boost::dll;
97  using fair::mq::tools::ToString;
98 
99  auto lib = shared_library{std::forward<Args>(args)...};
100  fgDLLKeepAlive.push_back(lib);
101 
102  fPluginFactories[pluginName] = import_alias<PluginFactory>(
103  shared_library{lib},
104  ToString("make_", pluginName, "_plugin")
105  );
106 
107  try
108  {
109  fPluginProgOptions.insert({
110  pluginName,
111  lib.get_alias<Plugin::ProgOptions()>(ToString("get_", pluginName, "_plugin_progoptions"))().value()
112  });
113  }
114  catch (const boost::bad_optional_access& e) { /* just ignore, if no prog options are declared */ }
115  }
116 
117  auto InstantiatePlugin(const std::string& pluginName) -> void;
118 
119  static const std::string fgkLibPrefix;
120  std::vector<boost::filesystem::path> fSearchPaths;
121  static std::vector<boost::dll::shared_library> fgDLLKeepAlive;
122  std::map<std::string, std::function<PluginFactory>> fPluginFactories;
123  std::unique_ptr<PluginServices> fPluginServices;
124  std::map<std::string, std::unique_ptr<Plugin>> fPlugins;
125  std::vector<std::string> fPluginOrder;
126  std::map<std::string, boost::program_options::options_description> fPluginProgOptions;
127 }; /* class PluginManager */
128 
129 } /* namespace mq */
130 } /* namespace fair */
131 
132 #endif /* FAIR_MQ_PLUGINMANAGER_H */
Facilitates communication between devices and plugins.
Definition: PluginServices.h:40
Definition: PluginManager.h:66
manages and owns plugin instances
Definition: PluginManager.h:49
Base class for FairMQ plugins.
Definition: Plugin.h:39
Definition: PluginManager.h:70
Tools for interfacing containers to the transport via polymorphic allocators.
Definition: DeviceRunner.h:23

privacy