SNode.C
Loading...
Searching...
No Matches
core::DynamicLoader Class Reference

#include <DynamicLoader.h>

Collaboration diagram for core::DynamicLoader:

Classes

struct  Library

Public Member Functions

 DynamicLoader ()=delete
 ~DynamicLoader ()=delete

Static Public Member Functions

static void * dlOpen (const std::string &libFile, int flags=RTLD_LOCAL|RTLD_LAZY)
static void dlCloseDelayed (void *handle)
static int dlClose (void *handle)
static const void * dlSym (void *handle, const std::string &symbol)
static const char * dlError ()

Static Private Member Functions

static std::string canonicalizePath (const std::string &libFile)
static int dlClose (Library &library)
static int realExecDlClose (const Library &library)
static void execDlCloseDeleyed ()
static void execDlCloseAll ()

Static Private Attributes

static std::map< std::string, LibrarydlOpenedLibraries
static std::map< void *, std::string > dlOpenedLibrariesByHandle
static std::list< std::string > closeQueue

Friends

class EventLoop
class EventMultiplexer

Detailed Description

Definition at line 58 of file DynamicLoader.h.

Constructor & Destructor Documentation

◆ DynamicLoader()

core::DynamicLoader::DynamicLoader ( )
delete

◆ ~DynamicLoader()

core::DynamicLoader::~DynamicLoader ( )
delete

Member Function Documentation

◆ canonicalizePath()

std::string core::DynamicLoader::canonicalizePath ( const std::string & libFile)
staticprivate

Definition at line 59 of file DynamicLoader.cpp.

59 {
60 std::string result = libFile;
61
62 try {
63 const std::filesystem::path p(libFile);
64 // Only try to resolve symlinks / normalize if the file actually exists.
65 // Otherwise (e.g. "libfoo.so" to be found via ld search path), keep as-is.
66 if (std::filesystem::exists(p)) {
67 result = std::filesystem::canonical(p).string();
68 }
69 } catch (...) {
70 // keep as-is
71 }
72
73 return result;
74 }

Referenced by dlOpen().

Here is the caller graph for this function:

◆ dlClose() [1/2]

int core::DynamicLoader::dlClose ( Library & library)
staticprivate

Definition at line 196 of file DynamicLoader.cpp.

196 {
197 int ret = 0;
198
199 ret = realExecDlClose(library);
200
201 if (ret != 0) {
202 LOG(TRACE) << " dlClose: " << DynamicLoader::dlError();
203 } else {
204 LOG(TRACE) << " dlClose: " << library.fileName << ": success";
205 }
206
207 return ret;
208 }
static int realExecDlClose(const Library &library)
static const char * dlError()

References dlError(), core::DynamicLoader::Library::fileName, and realExecDlClose().

Referenced by dlClose(), execDlCloseAll(), and execDlCloseDeleyed().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dlClose() [2/2]

int core::DynamicLoader::dlClose ( void * handle)
static

Definition at line 145 of file DynamicLoader.cpp.

145 {
146 int ret = 0;
147
148 if (handle == nullptr) {
149 LOG(TRACE) << "DynLoader: dlClose: handle is nullptr";
150 } else {
151 auto itHandle = dlOpenedLibrariesByHandle.find(handle);
152 if (itHandle == dlOpenedLibrariesByHandle.end()) {
153 LOG(TRACE) << "DynLoader: dlClose: " << handle << ": not opened using dlOpen";
154 } else {
155 auto itLib = dlOpenedLibraries.find(itHandle->second);
156 if (itLib == dlOpenedLibraries.end()) {
157 LOG(TRACE) << "DynLoader: dlClose: internal error: handle known but library record missing";
158 } else {
159 Library& lib = itLib->second;
160
161 if (lib.refCount > 0) {
162 --lib.refCount;
163 }
164
165 if (lib.refCount != 0) {
166 LOG(TRACE) << "DynLoader: dlClose: " << lib.fileName << ": still referenced (refCount=" << lib.refCount << ")";
167 } else {
168 lib.closePending = false;
169 ret = dlClose(lib);
170
171 dlOpenedLibrariesByHandle.erase(lib.handle);
172 dlOpenedLibraries.erase(itLib);
173 }
174 }
175 }
176 }
177
178 return ret;
179 }
static int dlClose(void *handle)
static std::map< void *, std::string > dlOpenedLibrariesByHandle
static std::map< std::string, Library > dlOpenedLibraries

References core::DynamicLoader::Library::closePending, dlClose(), dlOpenedLibraries, dlOpenedLibrariesByHandle, core::DynamicLoader::Library::fileName, core::DynamicLoader::Library::handle, and core::DynamicLoader::Library::refCount.

Referenced by web::http::SocketContextUpgradeFactorySelector< SocketContextUpgradeFactoryT >::load(), and web::websocket::SubProtocolFactorySelector< SubProtocolFactoryT >::load().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dlCloseDelayed()

void core::DynamicLoader::dlCloseDelayed ( void * handle)
static

Definition at line 114 of file DynamicLoader.cpp.

114 {
115 if (handle == nullptr) {
116 LOG(TRACE) << "DynLoader: dlCloseDelayed: handle is nullptr";
117 } else {
118 auto itHandle = dlOpenedLibrariesByHandle.find(handle);
119 if (itHandle == dlOpenedLibrariesByHandle.end()) {
120 LOG(TRACE) << "DynLoader: dlCloseDelayed: " << handle << ": not opened using dlOpen";
121 } else {
122 auto itLib = dlOpenedLibraries.find(itHandle->second);
123 if (itLib == dlOpenedLibraries.end()) {
124 LOG(TRACE) << "DynLoader: dlCloseDelayed: internal error: handle known but library record missing";
125 } else {
126 Library& lib = itLib->second;
127
128 if (lib.refCount > 0) {
129 --lib.refCount;
130 }
131
132 if (lib.refCount == 0) {
133 lib.closePending = true;
134 closeQueue.push_back(lib.canonicalFileName);
135 LOG(TRACE) << "DynLoader: dlCloseDelayed: " << lib.fileName;
136 } else {
137 LOG(TRACE) << "DynLoader: dlCloseDelayed: " << lib.fileName << ": still referenced (refCount=" << lib.refCount
138 << ")";
139 }
140 }
141 }
142 }
143 }
static std::list< std::string > closeQueue

References core::DynamicLoader::Library::canonicalFileName, core::DynamicLoader::Library::closePending, closeQueue, dlOpenedLibraries, dlOpenedLibrariesByHandle, core::DynamicLoader::Library::fileName, and core::DynamicLoader::Library::refCount.

Referenced by web::http::SocketContextUpgradeFactorySelector< SocketContextUpgradeFactoryT >::unload(), and web::websocket::SubProtocolFactorySelector< web::websocket::SubProtocolFactory< web::websocket::client::SubProtocol > >::unload().

Here is the caller graph for this function:

◆ dlError()

const char * core::DynamicLoader::dlError ( )
static

Definition at line 186 of file DynamicLoader.cpp.

186 {
187 const char* err = core::system::dlerror();
188 return err;
189 }
char * dlerror()
Definition dlfcn.cpp:67

References core::system::dlerror().

Referenced by dlClose(), dlOpen(), web::http::SocketContextUpgradeFactorySelector< SocketContextUpgradeFactoryT >::load(), and web::websocket::SubProtocolFactorySelector< SubProtocolFactoryT >::load().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dlOpen()

void * core::DynamicLoader::dlOpen ( const std::string & libFile,
int flags = RTLD_LOCAL | RTLD_LAZY )
static

Definition at line 76 of file DynamicLoader.cpp.

76 {
77 void* handle = nullptr;
78
79 const std::string canonicalFile = canonicalizePath(libFile);
80
81 auto it = dlOpenedLibraries.find(canonicalFile);
82 if (it != dlOpenedLibraries.end()) {
83 Library& lib = it->second;
84 ++lib.refCount;
85 lib.closePending = false;
86
87 LOG(TRACE) << "DynLoader: dlOpen: " << lib.fileName << ": already open (refCount=" << lib.refCount << ")";
88 handle = lib.handle;
89 } else {
90 // Clear possible stale error
92
93 handle = core::system::dlopen(libFile.c_str(), flags);
94 if (handle != nullptr) {
95 Library lib;
96 lib.fileName = libFile;
97 lib.canonicalFileName = canonicalFile;
98 lib.handle = handle;
99 lib.refCount = 1;
100 lib.closePending = false;
101
102 dlOpenedLibraries.emplace(canonicalFile, lib);
103 dlOpenedLibrariesByHandle.emplace(handle, canonicalFile);
104
105 LOG(TRACE) << "DynLoader: dlOpen: " << libFile << ": success";
106 } else {
107 LOG(TRACE) << "DynLoader: dlOpen: " << libFile << ": " << DynamicLoader::dlError();
108 }
109 }
110
111 return handle;
112 }
static std::string canonicalizePath(const std::string &libFile)
void * dlopen(const char *filename, int flags)
Definition dlfcn.cpp:52

References core::DynamicLoader::Library::canonicalFileName, canonicalizePath(), core::DynamicLoader::Library::closePending, dlError(), core::system::dlopen(), dlOpenedLibraries, dlOpenedLibrariesByHandle, core::DynamicLoader::Library::fileName, core::DynamicLoader::Library::handle, and core::DynamicLoader::Library::refCount.

Referenced by web::http::SocketContextUpgradeFactorySelector< SocketContextUpgradeFactoryT >::load(), and web::websocket::SubProtocolFactorySelector< SubProtocolFactoryT >::load().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dlSym()

const void * core::DynamicLoader::dlSym ( void * handle,
const std::string & symbol )
static

Definition at line 181 of file DynamicLoader.cpp.

181 {
182 const void* sym = core::system::dlsym(handle, symbol.c_str());
183 return sym;
184 }
void * dlsym(void *handle, const char *symbol)
Definition dlfcn.cpp:62

References core::system::dlsym().

Referenced by web::http::SocketContextUpgradeFactorySelector< SocketContextUpgradeFactoryT >::load(), and web::websocket::SubProtocolFactorySelector< SubProtocolFactoryT >::load().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ execDlCloseAll()

void core::DynamicLoader::execDlCloseAll ( )
staticprivate

Definition at line 237 of file DynamicLoader.cpp.

237 {
238 LOG(TRACE) << "DynLoader: execDlCloseAll";
239
240 for (auto& [canonical, library] : dlOpenedLibraries) {
241 (void) dlClose(library);
242 }
243
244 dlOpenedLibraries.clear();
246 closeQueue.clear();
247
248 LOG(TRACE) << "DynLoader: execDlCloseAll done";
249 }

References closeQueue, dlClose(), dlOpenedLibraries, and dlOpenedLibrariesByHandle.

Referenced by core::EventLoop::free().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ execDlCloseDeleyed()

void core::DynamicLoader::execDlCloseDeleyed ( )
staticprivate

Definition at line 210 of file DynamicLoader.cpp.

210 {
211 if (!closeQueue.empty()) {
212 LOG(TRACE) << "DynLoader: execDlCloseDeleyed";
213
214 for (const std::string& canonicalFile : closeQueue) {
215 auto it = dlOpenedLibraries.find(canonicalFile);
216 if (it == dlOpenedLibraries.end()) {
217 continue;
218 }
219
220 Library& lib = it->second;
221 if (!lib.closePending || lib.refCount != 0) {
222 continue;
223 }
224
225 lib.closePending = false;
226 (void) dlClose(lib);
227 dlOpenedLibrariesByHandle.erase(lib.handle);
228 dlOpenedLibraries.erase(it);
229 }
230
231 closeQueue.clear();
232
233 LOG(TRACE) << "DynLoader: execDlCloseDeleyed done";
234 }
235 }

References core::DynamicLoader::Library::closePending, closeQueue, dlClose(), dlOpenedLibraries, dlOpenedLibrariesByHandle, core::DynamicLoader::Library::handle, and core::DynamicLoader::Library::refCount.

Referenced by core::EventMultiplexer::releaseExpiredResources().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ realExecDlClose()

int core::DynamicLoader::realExecDlClose ( const Library & library)
staticprivate

Definition at line 191 of file DynamicLoader.cpp.

191 {
192 const int ret = core::system::dlclose(library.handle);
193 return ret;
194 }
int dlclose(void *handle)
Definition dlfcn.cpp:57

References core::system::dlclose(), and core::DynamicLoader::Library::handle.

Referenced by dlClose().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ EventLoop

friend class EventLoop
friend

Definition at line 90 of file DynamicLoader.h.

◆ EventMultiplexer

friend class EventMultiplexer
friend

Definition at line 91 of file DynamicLoader.h.

Member Data Documentation

◆ closeQueue

std::list< std::string > core::DynamicLoader::closeQueue
staticprivate

Definition at line 88 of file DynamicLoader.h.

Referenced by dlCloseDelayed(), execDlCloseAll(), and execDlCloseDeleyed().

◆ dlOpenedLibraries

std::map< std::string, DynamicLoader::Library > core::DynamicLoader::dlOpenedLibraries
staticprivate

Definition at line 86 of file DynamicLoader.h.

Referenced by dlClose(), dlCloseDelayed(), dlOpen(), execDlCloseAll(), and execDlCloseDeleyed().

◆ dlOpenedLibrariesByHandle

std::map< void *, std::string > core::DynamicLoader::dlOpenedLibrariesByHandle
staticprivate

Definition at line 87 of file DynamicLoader.h.

Referenced by dlClose(), dlCloseDelayed(), dlOpen(), execDlCloseAll(), and execDlCloseDeleyed().


The documentation for this class was generated from the following files: