-
Notifications
You must be signed in to change notification settings - Fork 67
Refactor backend library loading and rename Arrow suffix to PodioArrow #999
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
tmadlener
merged 8 commits into
AIDASoft:master
from
arnavdham:feature/arrow-dynamic-loading
Aug 13, 2026
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
7d9e3fb
dynamic loading
arnavdham 79ea01c
In type registry also
arnavdham b28d7a1
comments for clarification
arnavdham ba66727
Comments resolution.
arnavdham d4de8ab
removing libpodioArrow.so
arnavdham 27c31b5
generic library loader
arnavdham 1b000fc
resolving comments
arnavdham 36c12eb
Arrow->PodioAroow
arnavdham File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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,32 @@ | ||
| #ifndef PODIO_UTILITIES_BACKENDLIBRARYLOADER_H | ||
| #define PODIO_UTILITIES_BACKENDLIBRARYLOADER_H | ||
|
|
||
| #include <map> | ||
| #include <string> | ||
| #include <tuple> | ||
| #include <vector> | ||
|
|
||
| namespace podio { | ||
| namespace utilities { | ||
|
|
||
| class BackendLibraryLoader { | ||
| public: | ||
| enum class LoadStatus : short { Success = 0, AlreadyLoaded = 1, Error = 2 }; | ||
|
|
||
| BackendLibraryLoader(std::string envVarName, std::string libraryPattern, std::string logDesignator); | ||
| ~BackendLibraryLoader() = default; | ||
|
|
||
| private: | ||
| LoadStatus loadLib(const std::string& libname, const std::string& directory); | ||
| std::vector<std::tuple<std::string, std::string>> getLibNames() const; | ||
|
|
||
| std::string m_envVarName; | ||
| std::string m_libraryPattern; | ||
| std::string m_logDesignator; | ||
| std::map<std::string, void*> m_loadedLibs{}; | ||
| }; | ||
|
|
||
| } // namespace utilities | ||
| } // namespace podio | ||
|
|
||
| #endif // PODIO_UTILITIES_BACKENDLIBRARYLOADER_H |
This file contains hidden or 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 hidden or 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 hidden or 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,93 @@ | ||
| #include "podio/utilities/BackendLibraryLoader.h" | ||
| #include <cstdlib> | ||
| #include <dlfcn.h> | ||
| #include <filesystem> | ||
| #include <iostream> | ||
| #include <sstream> | ||
| #include <stdexcept> | ||
|
|
||
| namespace podio { | ||
| namespace utilities { | ||
|
|
||
| BackendLibraryLoader::BackendLibraryLoader(std::string envVarName, std::string libraryPattern, | ||
| std::string logDesignator) : | ||
| m_envVarName(std::move(envVarName)), | ||
| m_libraryPattern(std::move(libraryPattern)), | ||
| m_logDesignator(std::move(logDesignator)) { | ||
|
|
||
| for (const auto& [lib, dir] : getLibNames()) { | ||
| const auto status = loadLib(lib, dir); | ||
| switch (status) { | ||
| case LoadStatus::Success: | ||
| std::cerr << "Loaded " << m_logDesignator << " library \'" << lib << "\' (from " << dir << ")" << std::endl; | ||
| break; | ||
| case LoadStatus::AlreadyLoaded: | ||
| std::cerr << m_logDesignator << " library \'" << lib << "\' already loaded. Not loading again from " << dir | ||
| << std::endl; | ||
| break; | ||
| case LoadStatus::Error: { | ||
| const char* err = dlerror(); | ||
| std::cerr << "ERROR while loading " << m_logDesignator << " library \'" << lib << "\' (from " << dir | ||
| << "): " << (err ? err : "Unknown error") << std::endl; | ||
| break; | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| BackendLibraryLoader::LoadStatus BackendLibraryLoader::loadLib(const std::string& libname, | ||
| const std::string& directory) { | ||
| if (m_loadedLibs.find(libname) != m_loadedLibs.end()) { | ||
| return LoadStatus::AlreadyLoaded; | ||
| } | ||
| dlerror(); // Clear any existing error | ||
| void* libhandle = dlopen((directory + "/" + libname).c_str(), RTLD_LAZY | RTLD_GLOBAL); | ||
| if (libhandle) { | ||
| m_loadedLibs.insert({libname, libhandle}); | ||
| return LoadStatus::Success; | ||
| } | ||
|
|
||
| return LoadStatus::Error; | ||
| } | ||
|
|
||
| std::vector<std::tuple<std::string, std::string>> BackendLibraryLoader::getLibNames() const { | ||
| namespace fs = std::filesystem; | ||
| std::vector<std::tuple<std::string, std::string>> libs; | ||
|
|
||
| const auto ldLibPath = [this]() { | ||
| auto pathVar = std::getenv(m_envVarName.c_str()); | ||
| if (!pathVar) { | ||
| pathVar = std::getenv("LD_LIBRARY_PATH"); | ||
| } | ||
| return pathVar; | ||
| }(); | ||
| if (!ldLibPath) { | ||
| return libs; | ||
| } | ||
|
|
||
| std::string dir; | ||
| std::istringstream stream(ldLibPath); | ||
| while (std::getline(stream, dir, ':')) { | ||
| if (not fs::exists(dir)) { | ||
| continue; | ||
| } | ||
|
|
||
| for (auto& lib : fs::directory_iterator(dir)) { | ||
| const auto filename = lib.path().filename().string(); | ||
| if (filename.find(m_libraryPattern) != std::string::npos) { | ||
| libs.emplace_back(std::move(filename), dir); | ||
| } | ||
| } | ||
|
|
||
| if (std::getenv(m_envVarName.c_str()) && libs.empty()) { | ||
| throw std::runtime_error("No " + m_logDesignator + " libraries found in " + m_envVarName + ". Please set " + | ||
| m_envVarName + " to the directory containing the " + m_logDesignator + | ||
| " libraries or unset it to fallback to LD_LIBRARY_PATH."); | ||
| } | ||
| } | ||
|
|
||
| return libs; | ||
| } | ||
|
|
||
| } // namespace utilities | ||
| } // namespace podio |
This file contains hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for being rather slow here, but IIUC, this might happen on multiple threads concurrently here. The
getReader(potentially also thegetConverter, but there I haven't fully understood the logic yet, I think) is called in a section which podio assumes is safe to be called from multiple threads. In SIO we load the libraries during the construction of the reader. This can't be placed into theArrowConverterRegistryconstructor because we will actually try to call into that from the loaded libraries, I think. But maybe there is some place where we have slightly less potential problems with trying to load from multiple threads.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That was the question we had too. In the end, it seems like Arnav's implementation relies on a guarantee that static local variable initialization is thread safe in C++.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes, good point. I missed the
staticassignment in theloadXYZLibraries. In that case I think threading should pose no issues and, I think this also gives us a guarantee of happening exactly once.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So ig this can be merged now if there are no more comments?