9 #ifndef FAIR_MQ_PLUGINMANAGER_H
10 #define FAIR_MQ_PLUGINMANAGER_H
12 #include <fairmq/Plugin.h>
13 #include <fairmq/PluginServices.h>
14 #include <fairmq/tools/Strings.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>
49 using PluginFactory = std::unique_ptr<fair::mq::Plugin>(
PluginServices&);
56 LOG(debug) <<
"Shutting down Plugin Manager";
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; };
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;
71 static auto ProgramOptions() -> boost::program_options::options_description;
74 static auto LibPrefix() ->
const std::string& {
return fgkLibPrefix; }
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); } }
79 template<
typename... Args>
80 auto EmplacePluginServices(Args&&... args) ->
void { fPluginServices = std::make_unique<PluginServices>(std::forward<Args>(args)...); }
82 auto WaitForPluginsToReleaseDeviceControl() ->
void { fPluginServices->WaitForReleaseDeviceControl(); }
85 static auto ValidateSearchPath(
const boost::filesystem::path&) -> void;
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
93 using namespace boost::dll;
94 using fair::mq::tools::ToString;
96 auto lib = shared_library{std::forward<Args>(args)...};
97 fgDLLKeepAlive.push_back(lib);
99 fPluginFactories[pluginName] = import_alias<PluginFactory>(
101 ToString(
"make_", pluginName,
"_plugin")
106 fPluginProgOptions.insert({
108 lib.get_alias<Plugin::ProgOptions()>(ToString(
"get_", pluginName,
"_plugin_progoptions"))().value()
111 catch (
const boost::bad_optional_access& e) { }
114 auto InstantiatePlugin(
const std::string& pluginName) -> void;
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;