forked from nv-morpheus/MRC
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6764cbf
commit 863dfcd
Showing
10 changed files
with
361 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/** | ||
* SPDX-FileCopyrightText: Copyright (c) 2021-2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <dlfcn.h> | ||
#include <glog/logging.h> | ||
|
||
#include <map> | ||
#include <memory> | ||
#include <mutex> | ||
#include <sstream> | ||
|
||
namespace srf::modules { | ||
|
||
class ModulePluginLibrary | ||
{ | ||
using module_plugin_map_t = std::map<std::string, std::mutex>; | ||
|
||
public: | ||
ModulePluginLibrary(ModulePluginLibrary&&) = delete; | ||
ModulePluginLibrary(const ModulePluginLibrary&) = delete; | ||
|
||
~ModulePluginLibrary() = default; | ||
|
||
void operator=(const ModulePluginLibrary&) = delete; | ||
|
||
static std::unique_ptr<ModulePluginLibrary> Acquire(std::unique_ptr<ModulePluginLibrary> uptr_plugin, | ||
std::string plugin_library_path); | ||
|
||
// Configuration so that dependent libraries will be searched for in | ||
// 'path' during OpenLibraryHandle. | ||
void set_library_directory(const std::string& path); | ||
|
||
// Reset any configuration done by SetLibraryDirectory. | ||
void reset_library_directory(); | ||
|
||
/** | ||
* Load plugin module -- will load the plugin library and call its loader entrypoint to register | ||
* any modules it contains. | ||
*/ | ||
void load(); | ||
|
||
/** | ||
* Unload the plugin module -- this will call the unload entrypoint of the plugin, which will then | ||
* unload any registered models. | ||
*/ | ||
void unload(); | ||
|
||
|
||
/** | ||
* Return a list of modules published by the plugin | ||
*/ | ||
unsigned int list_modules(const char** list); | ||
|
||
private: | ||
explicit ModulePluginLibrary() = delete; | ||
explicit ModulePluginLibrary(std::string plugin_library_path) : | ||
m_plugin_library_path(std::move(plugin_library_path)) | ||
{} | ||
|
||
static std::mutex s_mutex; | ||
static module_plugin_map_t s_plugin_map; | ||
|
||
static const std::string PluginEntrypointLoad; | ||
static const std::string PluginEntrypointUnload; | ||
static const std::string PluginEntrypointList; | ||
|
||
void* m_plugin_handle{nullptr}; | ||
|
||
bool m_loaded{false}; | ||
std::string m_plugin_library_path{}; | ||
|
||
bool (*m_plugin_load)(); | ||
bool (*m_plugin_unload)(); | ||
unsigned int (*m_plugin_list)(const char**); | ||
|
||
void open_library_handle(); | ||
void get_plugin_entrypoint(const std::string& entrypoint_name, void** entrypoint); | ||
}; | ||
|
||
} // namespace srf::modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
/** | ||
* SPDX-FileCopyrightText: Copyright (c) 2021-2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#include "srf/experimental/modules/plugins.hpp" | ||
|
||
#include <iostream> | ||
#include <memory> | ||
#include <mutex> | ||
#include <string> | ||
|
||
namespace srf::modules { | ||
|
||
std::mutex ModulePluginLibrary::s_mutex{}; | ||
|
||
const std::string ModulePluginLibrary::PluginEntrypointList{"SRF_MODULE_entrypoint_list"}; | ||
const std::string ModulePluginLibrary::PluginEntrypointLoad{"SRF_MODULE_entrypoint_load"}; | ||
const std::string ModulePluginLibrary::PluginEntrypointUnload{"SRF_MODULE_entrypoint_unload"}; | ||
|
||
std::unique_ptr<ModulePluginLibrary> ModulePluginLibrary::Acquire(std::unique_ptr<ModulePluginLibrary> uptr_plugin, | ||
std::string plugin_library_path) | ||
{ | ||
std::lock_guard<decltype(s_mutex)> lock(s_mutex); | ||
|
||
uptr_plugin.reset(new ModulePluginLibrary(std::move(plugin_library_path))); | ||
|
||
return std::move(uptr_plugin); | ||
} | ||
|
||
void ModulePluginLibrary::set_library_directory(const std::string& path) | ||
{ | ||
throw std::runtime_error("Unimplemented"); | ||
} | ||
|
||
void ModulePluginLibrary::reset_library_directory() | ||
{ | ||
throw std::runtime_error("Unimplemented"); | ||
} | ||
|
||
unsigned int ModulePluginLibrary::list_modules(const char** list) | ||
{ | ||
return m_plugin_list(list); | ||
} | ||
|
||
void ModulePluginLibrary::load() | ||
{ | ||
if (m_loaded) | ||
{ | ||
return; | ||
} | ||
|
||
open_library_handle(); | ||
get_plugin_entrypoint(PluginEntrypointList, reinterpret_cast<void**>(&m_plugin_list)); | ||
get_plugin_entrypoint(PluginEntrypointLoad, reinterpret_cast<void**>(&m_plugin_load)); | ||
get_plugin_entrypoint(PluginEntrypointUnload, reinterpret_cast<void**>(&m_plugin_unload)); | ||
|
||
m_plugin_load(); | ||
m_loaded = true; | ||
} | ||
|
||
void ModulePluginLibrary::unload() | ||
{ | ||
if (!m_loaded) | ||
{ | ||
return; | ||
} | ||
|
||
m_plugin_unload(); | ||
|
||
if (dlclose(m_plugin_handle) != 0) | ||
{ | ||
std::stringstream sstream; | ||
|
||
sstream << "Failed to close plugin module -> " << dlerror(); | ||
VLOG(2) << sstream.str(); | ||
throw std::runtime_error(dlerror()); | ||
} | ||
|
||
m_plugin_load = nullptr; | ||
m_plugin_unload = nullptr; | ||
|
||
m_loaded = false; | ||
} | ||
|
||
void ModulePluginLibrary::open_library_handle() | ||
{ | ||
m_plugin_handle = dlopen(m_plugin_library_path.c_str(), RTLD_NOW | RTLD_LOCAL); | ||
if (m_plugin_handle == nullptr) | ||
{ | ||
std::stringstream sstream; | ||
|
||
sstream << "Failed to open plugin module -> " << dlerror(); | ||
VLOG(2) << sstream.str(); | ||
|
||
throw std::runtime_error(sstream.str()); | ||
} | ||
} | ||
|
||
void ModulePluginLibrary::get_plugin_entrypoint(const std::string& entrypoint_name, void** entrypoint) | ||
{ | ||
*entrypoint = nullptr; | ||
|
||
dlerror(); | ||
void* _fn = dlsym(m_plugin_handle, entrypoint_name.c_str()); | ||
|
||
const char* dlsym_error = dlerror(); | ||
if (dlsym_error != nullptr) | ||
{ | ||
std::stringstream sstream; | ||
|
||
sstream << "Failed to find entrypoint -> '" << entrypoint_name << "' in '" << m_plugin_library_path << " : " | ||
<< dlsym_error; | ||
|
||
VLOG(2) << sstream.str(); | ||
throw std::invalid_argument(sstream.str()); | ||
} | ||
|
||
*entrypoint = _fn; | ||
} | ||
|
||
} // namespace srf::modules |
Oops, something went wrong.