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#include "core/DynamicLoader.h"
21
22#ifndef DOXYGEN_SHOULD_SKIP_THIS
23
24#include "log/Logger.h"
25
26#include <algorithm>
27
28#endif /* DOXYGEN_SHOULD_SKIP_THIS */
29
30namespace core {
31
32 std::map<void*, DynamicLoader::Library> DynamicLoader::dlOpenedLibraries;
33 std::list<void*> DynamicLoader::closeHandles;
34
35 void* DynamicLoader::dlRegisterHandle(void* handle, const std::string& libFile) {
36 if (handle != nullptr) {
37 if (!dlOpenedLibraries.contains(handle)) {
38 dlOpenedLibraries[handle].fileName = libFile;
39 dlOpenedLibraries[handle].handle = handle;
40 }
41 LOG(TRACE) << "DynLoader: dlOpen: " << libFile << ": success";
42 } else {
43 LOG(TRACE) << "DynLoader: dlOpen: " << DynamicLoader::dlError();
44 }
45
46 return handle;
47 }
48
49 void DynamicLoader::dlCloseDelayed(void* handle) {
50 if (handle != nullptr) {
51 if (dlOpenedLibraries.contains(handle)) {
52 if (std::find(closeHandles.begin(), closeHandles.end(), handle) == closeHandles.end()) {
53 LOG(TRACE) << "DynLoader: dlCloseDelayed: " << dlOpenedLibraries[handle].fileName;
54
55 closeHandles.push_back(handle);
56 } else {
57 LOG(TRACE) << "DynLoader: dlCloseDelayed: " << dlOpenedLibraries[handle].fileName << ": already registered: ";
58 }
59 } else {
60 LOG(TRACE) << "DynLoader: dlCloseDelayed: " << handle << ": not opened using dlOpen";
61 }
62 } else {
63 LOG(TRACE) << "DynLoader: dlCloseDelayed: handle is nullptr";
64 }
65 }
66
67 int DynamicLoader::dlClose(void* handle) {
68 int ret = 0;
69
70 if (handle != nullptr) {
71 if (dlOpenedLibraries.contains(handle)) {
72 ret = dlClose(dlOpenedLibraries[handle]);
73
74 dlOpenedLibraries.erase(handle);
75 } else {
76 LOG(TRACE) << "DynLoader: dlCloseDelayed: " << handle << ": not opened using dlOpen";
77 }
78 } else {
79 LOG(TRACE) << "DynLoader: dlClose handle: nullptr";
80 }
81
82 return ret;
83 }
84
85 void* DynamicLoader::dlSym(void* handle, const std::string& symbol) {
86 return core::system::dlsym(handle, symbol.c_str());
87 }
88
89 char* DynamicLoader::dlError() {
90 return core::system::dlerror();
91 }
92
93 int DynamicLoader::realExecDlClose(const Library& library) {
94 return core::system::dlclose(library.handle);
95 }
96
97 int DynamicLoader::dlClose(const Library& library) {
98 int ret = 0;
99 ret = realExecDlClose(library);
100
101 if (ret != 0) {
102 LOG(TRACE) << " dlClose: " << DynamicLoader::dlError();
103 } else {
104 LOG(TRACE) << " dlClose: " << library.fileName << ": success";
105 }
106
107 return ret;
108 }
109
110 void DynamicLoader::execDlCloseDeleyed() {
111 if (!closeHandles.empty()) {
112 LOG(TRACE) << "DynLoader: execDlCloseDeleyed";
113
114 for (void* handle : closeHandles) {
115 dlClose(dlOpenedLibraries[handle]);
116 dlOpenedLibraries.erase(handle);
117 }
118
119 closeHandles.clear();
120
121 LOG(TRACE) << "DynLoader: execDlCloseDeleyed done";
122 }
123 }
124
125 void DynamicLoader::execDlCloseAll() {
126 LOG(TRACE) << "DynLoader: execDlCloseAll";
127
128 for (auto& [handle, library] : dlOpenedLibraries) {
129 dlClose(library);
130 }
131
132 dlOpenedLibraries.clear();
133 closeHandles.clear();
134
135 LOG(TRACE) << "DynLoader: execDlCloseAll done";
136 }
137
138} // namespace core