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

privacy