Project
Loading...
Searching...
No Matches
PluginManager.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11#ifndef O2_FRAMEWORK_PLUGIN_MANAGER_H_
12#define O2_FRAMEWORK_PLUGIN_MANAGER_H_
13
14#include "Framework/Plugins.h"
15#include <cstring>
16#include <uv.h>
17#include <functional>
18
19// Struct to hold live plugin information which the plugin itself cannot
20// know and that is owned by the framework.
21struct PluginInfo {
22 uv_lib_t* dso = nullptr;
23 std::string name;
25};
26
27// Struct to hold information about the location of a plugin
29 std::string name;
30 std::string library;
31};
32
33namespace o2::framework
34{
37
38 template <typename T>
39 static T* getByName(DPLPluginHandle* handle, char const* name)
40 {
41 while (handle != nullptr) {
42 if (strncmp(handle->name, name, strlen(name)) == 0) {
43 return reinterpret_cast<T*>(handle->instance);
44 }
45 handle = handle->previous;
46 }
47 return nullptr;
48 }
52 static void load(std::vector<PluginInfo>& infos, const char* dso, std::function<void(DPLPluginHandle*)>& onSuccess);
56 static auto loadAlgorithmFromPlugin(std::string library, std::string plugin, ConfigContext const& context) -> AlgorithmSpec;
59 static auto wrapAlgorithm(AlgorithmSpec const& spec, WrapperProcessCallback&& wrapper) -> AlgorithmSpec;
60
62 static std::vector<LoadablePlugin> parsePluginSpecString(char const* str);
63
64 template <typename CONCRETE, typename PLUGIN>
65 static void loadFromPlugin(std::vector<LoadablePlugin> const& loadablePlugins, std::vector<CONCRETE>& specs)
66 {
67 struct LoadedDSO {
68 std::string library;
69 uv_lib_t handle;
70 };
71
72 struct LoadedPlugin {
73 std::string name;
74 PLUGIN* factory;
75 };
76 std::vector<LoadedDSO> loadedDSOs;
77 std::vector<LoadedPlugin> loadedPlugins;
78 for (auto& loadablePlugin : loadablePlugins) {
79 auto loadedDSO = std::find_if(loadedDSOs.begin(), loadedDSOs.end(), [&loadablePlugin](auto& dso) {
80 return dso.library == loadablePlugin.library;
81 });
82
83 if (loadedDSO == loadedDSOs.end()) {
84 uv_lib_t handle;
85#ifdef __APPLE__
86 auto libraryName = fmt::format("lib{}.dylib", loadablePlugin.library);
87#else
88 auto libraryName = fmt::format("lib{}.so", loadablePlugin.library);
89#endif
90 auto ret = uv_dlopen(libraryName.c_str(), &handle);
91 if (ret != 0) {
92 LOGP(error, "Could not load library {}", loadablePlugin.library);
93 LOG(error) << uv_dlerror(&handle);
94 continue;
95 }
96 loadedDSOs.push_back({loadablePlugin.library, handle});
97 loadedDSO = loadedDSOs.end() - 1;
98 }
99 int result = 0;
100
101 auto loadedPlugin = std::find_if(loadedPlugins.begin(), loadedPlugins.end(), [&loadablePlugin](auto& plugin) {
102 return plugin.name == loadablePlugin.name;
103 });
104
105 if (loadedPlugin == loadedPlugins.end()) {
106 DPLPluginHandle* (*dpl_plugin_callback)(DPLPluginHandle*);
107 result = uv_dlsym(&loadedDSO->handle, "dpl_plugin_callback", (void**)&dpl_plugin_callback);
108 if (result == -1) {
109 LOG(error) << uv_dlerror(&loadedDSO->handle);
110 continue;
111 }
112
113 DPLPluginHandle* pluginInstance = dpl_plugin_callback(nullptr);
114 PLUGIN* factory = PluginManager::getByName<PLUGIN>(pluginInstance, loadablePlugin.name.c_str());
115 if (factory == nullptr) {
116 LOGP(error, "Could not find service {} in library {}", loadablePlugin.name, loadablePlugin.library);
117 continue;
118 }
119
120 loadedPlugins.push_back({loadablePlugin.name, factory});
121 loadedPlugin = loadedPlugins.begin() + loadedPlugins.size() - 1;
122 }
123 assert(loadedPlugin != loadedPlugins.end());
124 assert(loadedPlugin->factory != nullptr);
125
126 CONCRETE* spec = loadedPlugin->factory->create();
127 if (!spec) {
128 LOG(error) << "Plugin " << loadablePlugin.name << " could not be created";
129 continue;
130 }
131 LOGP(debug, "Loading service {} from {}", loadablePlugin.name, loadablePlugin.library);
132 specs.push_back(*spec);
133 }
134 }
135};
136
137} // namespace o2::framework
138#endif // O2_FRAMEWORK_PLUGIN_MANAGER_H_
std::ostringstream debug
GLuint64EXT * result
Definition glcorearb.h:5662
GLuint const GLchar * name
Definition glcorearb.h:781
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
void * instance
Definition Plugins.h:93
char const * name
Definition Plugins.h:94
DPLPluginHandle * previous
Definition Plugins.h:96
std::string library
std::string name
std::string name
uv_lib_t * dso
DPLPluginHandle * instance
std::function< void(ProcessingContext &)> ProcessCallback
static std::vector< LoadablePlugin > parsePluginSpecString(char const *str)
Parse a comma separated list of <library>:<plugin-name> plugin declarations.
static T * getByName(DPLPluginHandle *handle, char const *name)
static auto loadAlgorithmFromPlugin(std::string library, std::string plugin, ConfigContext const &context) -> AlgorithmSpec
static void load(std::vector< PluginInfo > &infos, const char *dso, std::function< void(DPLPluginHandle *)> &onSuccess)
static void loadFromPlugin(std::vector< LoadablePlugin > const &loadablePlugins, std::vector< CONCRETE > &specs)
std::function< void(AlgorithmSpec::ProcessCallback &, ProcessingContext &)> WrapperProcessCallback
static auto wrapAlgorithm(AlgorithmSpec const &spec, WrapperProcessCallback &&wrapper) -> AlgorithmSpec
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
const std::string str