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