23#include <tbb/concurrent_unordered_map.h>
24#include <unordered_set>
36 tbb::concurrent_unordered_map<std::string, std::function<std::unique_ptr<AsgComponent>(
const std::string& name)>> s_factories;
37 tbb::concurrent_unordered_map<std::string,std::string> s_typeModuleMap;
39 struct ModuleData
final
41 std::atomic<bool> loaded{
false};
44 tbb::concurrent_unordered_map<std::string,ModuleData> s_modules;
49 StatusCode registerComponentFactory (
const std::string& type,
const std::function<std::unique_ptr<AsgComponent>(
const std::string& name)>& factory)
51 using namespace msgComponentConfig;
52 if (!s_factories.emplace (type, factory).second)
54 ATH_MSG_ERROR (
"attempt to register a factory for type " << type <<
" that already has a factory");
55 return StatusCode::FAILURE;
57 return StatusCode::SUCCESS;
62 const std::function<std::unique_ptr<AsgComponent>(
const std::string& name)> *getComponentFactory (
const std::string& type)
64 using namespace msgComponentConfig;
65 if (
auto iter = s_factories.find (type); iter != s_factories.end())
67 static std::once_flag
flag;
68 std::call_once (flag, [&] () {
69 const char *
path = gSystem->Getenv (
"LD_LIBRARY_PATH");
71 std::regex pathRegex (
"\\.asgcomponents$");
72 for (
auto&& part : std::views::split(std::string_view(path),
':'))
74 std::string_view
p(&*
part.begin(), std::ranges::distance(part));
75 if (
p.empty())
continue;
77 if (!std::filesystem::exists(p, ec))
79 ANA_MSG_DEBUG (
"skipping non-existent directory for component factory maps: " << p);
82 ANA_MSG_DEBUG (
"checking for component factory map in " << p);
84 for (
auto const& entry : std::filesystem::directory_iterator(p))
86 if (std::regex_search (
entry.path().filename().string(), pathRegex))
87 loadComponentFactoryMap (
entry.path());
91 if (
auto iter = s_typeModuleMap.find (type); iter != s_typeModuleMap.end())
93 ATH_MSG_DEBUG (
"loading component factory module for type " << type <<
" from " <<
iter->second);
94 loadComponentFactoryModule (
iter->second);
97 ATH_MSG_DEBUG (
"no component factory module known for type " << type);
100 if (
auto iter = s_factories.find (type); iter != s_factories.end())
101 return &
iter->second;
104 ATH_MSG_WARNING (
"no component factory found for type " << type <<
" even after loading its module");
111 std::vector<std::string> getLoadedComponentFactoryTypes ()
113 using namespace msgComponentConfig;
115 std::vector<std::string>
result;
116 result.reserve (s_factories.size());
117 for (
const auto& pair : s_factories)
118 result.push_back (pair.first);
125 void loadComponentFactoryModule (
const std::string& moduleName,
const std::string& modulePath)
127 using namespace msgComponentConfig;
128 ATH_MSG_DEBUG (
"loading component factory module " << moduleName);
130 auto [
iter, inserted] = s_modules.emplace(std::piecewise_construct, std::forward_as_tuple(moduleName), std::forward_as_tuple());
131 if (
iter->second.loaded ==
true)
133 ATH_MSG_DEBUG (
"component factory module " << moduleName <<
" already loaded");
136 std::scoped_lock lock(
iter->second.mutex);
137 if (
iter->second.loaded ==
true)
139 ATH_MSG_DEBUG (
"component factory module " << moduleName <<
" already loaded");
145 if (!modulePath.empty())
146 path = modulePath +
"/" + moduleName;
148 path = gSystem->DynamicPathName (moduleName.c_str());
149 ANA_MSG_DEBUG (
"loading component factory module from " << path);
150 if (gSystem->Load (
path.c_str()) < 0)
152 ATH_MSG_FATAL (
"failed to preload component factory module " << moduleName);
155 iter->second.loaded =
true;
160 void loadComponentFactoryMap (
const std::string& path)
162 using namespace msgComponentConfig;
163 ATH_MSG_DEBUG (
"loading component factory map from " << path);
165 std::ifstream inputStream (path);
168 ATH_MSG_FATAL (
"failed to open component factory map file " << path);
171 std::unordered_set<std::string> foundModules;
172 std::unordered_set<std::string> skippedModules;
174 while (inputStream >> moduleName >> typeName)
180 if (
auto iter = s_modules.find(moduleName); iter != s_modules.end())
182 if (skippedModules.emplace(moduleName).second)
183 ANA_MSG_DEBUG (
"skipping information on " << moduleName <<
" from " << path <<
" because it has already been described in another file");
186 foundModules.insert(moduleName);
187 ATH_MSG_DEBUG (
"registering component factory type " << typeName <<
" from module " << moduleName);
188 auto [
iter, success] = s_typeModuleMap.emplace (typeName, moduleName);
191 if (
iter->second != moduleName)
193 ATH_MSG_FATAL (
"conflicting component factory module for type " << typeName
194 <<
": already registered from " <<
iter->second
195 <<
", but trying to register from " << moduleName);
199 ATH_MSG_DEBUG (
"component factory type " << typeName <<
" registered twice for module " << moduleName);
203 for (
const auto& moduleName : foundModules)
204 s_modules.emplace(std::piecewise_construct, std::forward_as_tuple(moduleName), std::forward_as_tuple());
#define ATH_MSG_WARNING(x)
::StatusCode StatusCode
StatusCode definition for legacy code.
path
python interpreter configuration --------------------------------------—
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.