DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
DalFactory.cpp
Go to the documentation of this file.
2
3#include "ers/ers.hpp"
5
8#include "conffwk/Errors.hpp"
9#include "conffwk/Schema.hpp"
10
11#include <dlfcn.h>
12
13namespace dunedaq {
14namespace conffwk {
15
16const std::string&
17DalFactory::get_known_class_name_ref(const std::string& name)
18{
19 std::lock_guard<std::mutex> scoped_lock(m_known_class_mutex);
20 return *m_known_classes.emplace(name).first;
21}
22
23bool
24DalFactory::try_load_class_library(Configuration& db, const std::string& class_name)
25{
26
27 auto& c = db.get_class_info(class_name);
28 TLOG_DEBUG(1) << "Resolvung dal library for class " << class_name;
29
30 std::string file = c.p_schema_path;
31 std::string search{ "/schema/" };
32 auto start = file.rfind(search);
33 if (start == std::string::npos) {
34 throw(DalPackageNameNotFound(ERS_HERE, class_name, file));
35 }
36 start += search.size();
37 auto end = file.find("/", start);
38 if (end == std::string::npos) {
39 throw(DalPackageNameNotFound(ERS_HERE, class_name, file));
40 }
41
42 std::string package = file.substr(start, end - start);
43 std::string library = "lib" + package + "_dal.so";
44 TLOG_DEBUG(1) << "Loading dal library " << library << " for class " << class_name;
45
46 auto handle = dlopen(library.c_str(), RTLD_LAZY | RTLD_GLOBAL);
47 if (handle == nullptr) {
48 throw(LoadDalFailed(ERS_HERE, library));
49 }
50
51 return handle != nullptr;
52}
53
57conffwk::DalObject*
58DalFactory::make(conffwk::DalRegistry& reg, conffwk::ConfigObject& o, bool upcast_unregistered)
59{
60
61 TLOG_DEBUG(50) << "Building object " << o.UID() << " of class " << o.class_name();
62
63 auto it = m_creators.find(o.class_name());
64
65 if (it == m_creators.end()) {
66 TLOG_DEBUG(50) << "Constructor for class " << o.class_name() << " not found";
67
68 if (!this->try_load_class_library(reg.configuration(), o.class_name())) {
69 throw NotFound(ERS_HERE, "class", o.class_name().c_str());
70 }
71 it = m_creators.find(o.class_name());
72 if (it == m_creators.end()) {
73 throw dunedaq::conffwk::NotFound(ERS_HERE, "class", o.class_name().c_str());
74 }
75 } else {
76 TLOG() << ">>> Constructor for class " << o.class_name() << " found";
77 }
78
79 auto dal_obj = it->second(reg, o);
80 TLOG_DEBUG(50) << "Object " << o.UID() << " of class " << o.class_name() << " created " << (void*)dal_obj;
81
82 return dal_obj;
83}
84
88conffwk::DalObject*
89DalFactory::make(conffwk::DalRegistry& reg, conffwk::ConfigObject& o, const std::string& fallback_unregistred)
90{
91
92 TLOG_DEBUG(50) << "Building object " << o.UID() << " of class " << o.class_name();
93
94 auto it = m_creators.find(o.class_name());
95
96 if (it == m_creators.end()) {
97 if (!this->try_load_class_library(reg.configuration(), o.class_name())) {
98 throw NotFound(ERS_HERE, "class", o.class_name().c_str());
99 }
100 it = m_creators.find(o.class_name());
101 if (it == m_creators.end()) {
102 throw dunedaq::conffwk::NotFound(ERS_HERE, "class", o.class_name().c_str());
103 }
104 }
105
106 auto dal_obj = it->second(reg, o);
107 TLOG_DEBUG(50) << "Object " << o.UID() << " of class " << o.class_name() << " created " << (void*)dal_obj;
108
109 return dal_obj;
110}
111
112DalFactory&
113DalFactory::instance()
114{
115 static DalFactory* instance = ers::SingletonCreator<DalFactory>::create();
116 return *instance;
117}
118
119DalObject*
120DalFactory::get(Configuration& db, ConfigObject& obj, const std::string& uid, bool upcast_unregistered) const
121{
122 return (*instance().functions(db, obj.class_name(), upcast_unregistered).m_creator_fn)(db, obj, uid);
123}
124
125DalObject*
126DalFactory::get(Configuration& db, ConfigObject& obj, const std::string& uid, const std::string& class_name) const
127{
128 return (*instance().functions(db, class_name, false).m_creator_fn)(db, obj, uid);
129}
130
131const DalFactoryFunctions&
132DalFactory::functions(Configuration& db, const std::string& name, bool upcast_unregistered)
133{
134 auto it = m_classes.find(name);
135
136 if (it == m_classes.end()) {
137 if (!this->try_load_class_library(db, name)) {
138 throw NotFound(ERS_HERE, "class", name.c_str());
139 }
140 it = m_classes.find(name);
141 if (it == m_classes.end()) {
142 throw dunedaq::conffwk::NotFound(ERS_HERE, "class", name.c_str());
143 }
144 }
145
146 return it->second;
147}
148
149const std::string&
150DalFactory::class4algo(Configuration& db, const std::string& name, const std::string& algorithm) const
151{
152 for (const auto& x : m_classes)
153 if (x.second.m_algorithms.find(algorithm) != x.second.m_algorithms.end() && db.try_cast(x.first, name))
154 return x.first;
155
156 static const std::string empty;
157 return empty;
158}
159
160const DalFactoryFunctions&
161DalFactory::functions(const std::string& name) const
162{
163 auto it = m_classes.find(name);
164
165 ERS_ASSERT_MSG((it != m_classes.end()), "writer lock was not initialized");
166
167 return it->second;
168}
169
170} // namespace conffwk
171} // namespace dunedaq
#define ERS_ASSERT_MSG(expression, message)
#define ERS_HERE
Defines base class for cache of template objects.
conffwk entry point
#define TLOG_DEBUG(lvl,...)
Definition Logging.hpp:116
#define TLOG(...)
Definition macro.hpp:21
The DUNE-DAQ namespace.