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