FairMQ  1.3.7
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/Tools.h>
15 #include <FairMQDevice.h>
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 #include <functional>
25 #include <map>
26 #include <memory>
27 #include <stdexcept>
28 #include <string>
29 #include <tuple>
30 #include <vector>
31 
32 namespace fair
33 {
34 namespace mq
35 {
36 
48 {
49  public:
50  using PluginFactory = std::unique_ptr<fair::mq::Plugin>(PluginServices&);
51 
52  PluginManager();
53  PluginManager(const std::vector<std::string> args);
54 
55  ~PluginManager()
56  {
57  LOG(debug) << "Shutting down Plugin Manager";
58  }
59 
60  auto SetSearchPaths(const std::vector<boost::filesystem::path>&) -> void;
61  auto AppendSearchPath(const boost::filesystem::path&) -> void;
62  auto PrependSearchPath(const boost::filesystem::path&) -> void;
63  auto SearchPaths() const -> const std::vector<boost::filesystem::path>& { return fSearchPaths; }
64  struct BadSearchPath : std::invalid_argument { using std::invalid_argument::invalid_argument; };
65 
66  auto LoadPlugin(const std::string& pluginName) -> void;
67  auto LoadPlugins(const std::vector<std::string>& pluginNames) -> void { for(const auto& pluginName : pluginNames) { LoadPlugin(pluginName); } }
68  struct PluginLoadError : std::runtime_error { using std::runtime_error::runtime_error; };
69  auto InstantiatePlugins() -> void;
70  struct PluginInstantiationError : std::runtime_error { using std::runtime_error::runtime_error; };
71 
72  static auto ProgramOptions() -> boost::program_options::options_description;
73  struct ProgramOptionsParseError : std::runtime_error { using std::runtime_error::runtime_error; };
74 
75  static auto LibPrefix() -> const std::string& { return fgkLibPrefix; }
76 
77  auto ForEachPlugin(std::function<void (Plugin&)> func) -> void { for(const auto& p : fPluginOrder) { func(*fPlugins[p]); } }
78  auto ForEachPluginProgOptions(std::function<void (boost::program_options::options_description)> func) const -> void { for(const auto& pair : fPluginProgOptions) { func(pair.second); } }
79 
80  template<typename... Args>
81  auto EmplacePluginServices(Args&&... args) -> void { fPluginServices = fair::mq::tools::make_unique<PluginServices>(std::forward<Args>(args)...); };
82 
83  auto WaitForPluginsToReleaseDeviceControl() -> void { fPluginServices->WaitForReleaseDeviceControl(); }
84 
85  private:
86  static auto ValidateSearchPath(const boost::filesystem::path&) -> void;
87 
88  auto LoadPluginPrelinkedDynamic(const std::string& pluginName) -> void;
89  auto LoadPluginDynamic(const std::string& pluginName) -> void;
90  auto LoadPluginStatic(const std::string& pluginName) -> void;
91  template<typename... Args>
92  auto LoadSymbols(const std::string& pluginName, Args&&... args) -> void
93  {
94  using namespace boost::dll;
95  using fair::mq::tools::ToString;
96 
97  auto lib = shared_library{std::forward<Args>(args)...};
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  std::map<std::string, std::function<PluginFactory>> fPluginFactories;
119  std::unique_ptr<PluginServices> fPluginServices;
120  std::map<std::string, std::unique_ptr<Plugin>> fPlugins;
121  std::vector<std::string> fPluginOrder;
122  std::map<std::string, boost::program_options::options_description> fPluginProgOptions;
123 }; /* class PluginManager */
124 
125 } /* namespace mq */
126 } /* namespace fair */
127 
128 #endif /* FAIR_MQ_PLUGINMANAGER_H */
Facilitates communication between devices and plugins.
Definition: PluginServices.h:38
Definition: PluginManager.h:64
manages and owns plugin instances
Definition: PluginManager.h:47
Base class for FairMQ plugins.
Definition: Plugin.h:38
Definition: PluginManager.h:68
Tools for interfacing containers to the transport via polymorphic allocators.
Definition: DeviceRunner.h:23

privacy