SNode.C
Loading...
Searching...
No Matches
DynamicLoader.cpp
Go to the documentation of this file.
1/*
2 * SNode.C - A Slim Toolkit for Network Communication
3 * Copyright (C) Volker Christian <me@vchrist.at>
4 * 2020, 2021, 2022, 2023, 2024, 2025
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20/*
21 * MIT License
22 *
23 * Permission is hereby granted, free of charge, to any person obtaining a copy
24 * of this software and associated documentation files (the "Software"), to deal
25 * in the Software without restriction, including without limitation the rights
26 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
27 * copies of the Software, and to permit persons to whom the Software is
28 * furnished to do so, subject to the following conditions:
29 *
30 * The above copyright notice and this permission notice shall be included in
31 * all copies or substantial portions of the Software.
32 *
33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
39 * THE SOFTWARE.
40 */
41
42#include "core/DynamicLoader.h"
43
44#ifndef DOXYGEN_SHOULD_SKIP_THIS
45
46#include "log/Logger.h"
47
48#include <algorithm>
49
50#endif /* DOXYGEN_SHOULD_SKIP_THIS */
51
52namespace core {
53
55 std::list<void*> DynamicLoader::closeHandles;
56
57 void* DynamicLoader::dlRegisterHandle(void* handle, const std::string& libFile) {
58 if (handle != nullptr) {
59 if (!dlOpenedLibraries.contains(handle)) {
60 dlOpenedLibraries[handle].fileName = libFile;
61 dlOpenedLibraries[handle].handle = handle;
62 }
63 LOG(TRACE) << "DynLoader: dlOpen: " << libFile << ": success";
64 } else {
65 LOG(TRACE) << "DynLoader: dlOpen: " << DynamicLoader::dlError();
66 }
67
68 return handle;
69 }
70
71 void DynamicLoader::dlCloseDelayed(void* handle) {
72 if (handle != nullptr) {
73 if (dlOpenedLibraries.contains(handle)) {
74 if (std::find(closeHandles.begin(), closeHandles.end(), handle) == closeHandles.end()) {
75 LOG(TRACE) << "DynLoader: dlCloseDelayed: " << dlOpenedLibraries[handle].fileName;
76
77 closeHandles.push_back(handle);
78 } else {
79 LOG(TRACE) << "DynLoader: dlCloseDelayed: " << dlOpenedLibraries[handle].fileName << ": already registered: ";
80 }
81 } else {
82 LOG(TRACE) << "DynLoader: dlCloseDelayed: " << handle << ": not opened using dlOpen";
83 }
84 } else {
85 LOG(TRACE) << "DynLoader: dlCloseDelayed: handle is nullptr";
86 }
87 }
88
89 int DynamicLoader::dlClose(void* handle) {
90 int ret = 0;
91
92 if (handle != nullptr) {
93 if (dlOpenedLibraries.contains(handle)) {
94 ret = dlClose(dlOpenedLibraries[handle]);
95
96 dlOpenedLibraries.erase(handle);
97 } else {
98 LOG(TRACE) << "DynLoader: dlCloseDelayed: " << handle << ": not opened using dlOpen";
99 }
100 } else {
101 LOG(TRACE) << "DynLoader: dlClose handle: nullptr";
102 }
103
104 return ret;
105 }
106
107 void* DynamicLoader::dlSym(void* handle, const std::string& symbol) {
108 return core::system::dlsym(handle, symbol.c_str());
109 }
110
112 return core::system::dlerror();
113 }
114
115 int DynamicLoader::realExecDlClose(const Library& library) {
116 return core::system::dlclose(library.handle);
117 }
118
119 int DynamicLoader::dlClose(const Library& library) {
120 int ret = 0;
121 ret = realExecDlClose(library);
122
123 if (ret != 0) {
124 LOG(TRACE) << " dlClose: " << DynamicLoader::dlError();
125 } else {
126 LOG(TRACE) << " dlClose: " << library.fileName << ": success";
127 }
128
129 return ret;
130 }
131
133 if (!closeHandles.empty()) {
134 LOG(TRACE) << "DynLoader: execDlCloseDeleyed";
135
136 for (void* handle : closeHandles) {
138 dlOpenedLibraries.erase(handle);
139 }
140
141 closeHandles.clear();
142
143 LOG(TRACE) << "DynLoader: execDlCloseDeleyed done";
144 }
145 }
146
148 LOG(TRACE) << "DynLoader: execDlCloseAll";
149
150 for (auto& [handle, library] : dlOpenedLibraries) {
151 dlClose(library);
152 }
153
154 dlOpenedLibraries.clear();
155 closeHandles.clear();
156
157 LOG(TRACE) << "DynLoader: execDlCloseAll done";
158 }
159
160} // namespace core
static void * dlRegisterHandle(void *handle, const std::string &libFile)
static char * dlError()
static int realExecDlClose(const Library &library)
static std::list< void * > closeHandles
static int dlClose(void *handle)
static std::map< void *, Library > dlOpenedLibraries
static void * dlSym(void *handle, const std::string &symbol)
static void execDlCloseDeleyed()
static int dlClose(const Library &library)
static void execDlCloseAll()
static void dlCloseDelayed(void *handle)
int dlclose(void *handle)
Definition dlfcn.cpp:57
void * dlsym(void *handle, const char *symbol)
Definition dlfcn.cpp:62
char * dlerror()
Definition dlfcn.cpp:67