From 6c415c67011532fc0fb7c3051a4cf657ea93dfe0 Mon Sep 17 00:00:00 2001 From: Patrick Venture Date: Wed, 14 Nov 2018 14:01:36 -0800 Subject: bugfix: load handlers and use factory symbol Use a predefined factory symbol to build each handler after loading the library. Change-Id: I0369c6e46a57c2e8533409d8b06eb74a3962434c Signed-off-by: Patrick Venture --- configure.ac | 2 +- example/example.cpp | 16 +++++++++++----- example/example.hpp | 15 +++++++++++++++ utils.cpp | 33 ++++++++++++++++++++++++++++++++- 4 files changed, 59 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index efdd0b8..db3bc83 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ AX_CXX_COMPILE_STDCXX_17([noext]) AX_APPEND_COMPILE_FLAGS([-Wall -Werror], [CXXFLAGS]) # Checks for library functions. -LT_INIT([dlopen]) # Required for systemd linking +LT_INIT([dlopen disable-static shared]) # Required for systemd linking LT_LIB_DLLOAD # Checks for libraries. diff --git a/example/example.cpp b/example/example.cpp index 929e4d1..cc36e88 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -181,11 +181,17 @@ void setupExampleHandler() __attribute__((constructor)); void setupExampleHandler() { - auto* manager = getBlobManager(); - if (!manager->registerHandler(std::make_unique())) - { - log("Failed to register Example Handler"); - } + // You don't need to do anything in the constructor. } } // namespace blobs + +/** + * This method is required by the blob manager. + * + * It is called to grab a handler for registering the blob handler instance. + */ +std::unique_ptr createHandler() +{ + return std::make_unique(); +} diff --git a/example/example.hpp b/example/example.hpp index a85c275..335eade 100644 --- a/example/example.hpp +++ b/example/example.hpp @@ -1,10 +1,25 @@ #pragma once #include +#include #include #include #include +#ifdef __cplusplus +extern "C" { +#endif + +/** + * This method must be declared as extern C for blob manager to lookup the + * symbol. + */ +std::unique_ptr createHandler(); + +#ifdef __cplusplus +} +#endif + namespace blobs { diff --git a/utils.cpp b/utils.cpp index 5253c1c..2395a2e 100644 --- a/utils.cpp +++ b/utils.cpp @@ -2,7 +2,9 @@ #include +#include #include +#include #include #include @@ -12,9 +14,13 @@ namespace blobs namespace fs = std::experimental::filesystem; using namespace phosphor::logging; +using HandlerFactory = std::unique_ptr (*)(); + void loadLibraries(const std::string& path) { void* libHandle = NULL; + HandlerFactory factory; + auto* manager = getBlobManager(); for (const auto& p : fs::recursive_directory_iterator(path)) { @@ -30,12 +36,37 @@ void loadLibraries(const std::string& path) continue; } - libHandle = dlopen(ps.c_str(), RTLD_NOW); + libHandle = dlopen(ps.c_str(), RTLD_NOW | RTLD_GLOBAL); if (!libHandle) { log("ERROR opening", entry("HANDLER=%s", ps.c_str()), entry("ERROR=%s", dlerror())); + continue; } + + dlerror(); /* Clear any previous error. */ + + factory = + reinterpret_cast(dlsym(libHandle, "createHandler")); + + const char* error = dlerror(); + if (error) + { + log("ERROR loading symbol", + entry("HANDLER=%s", ps.c_str()), + entry("ERROR=%s", error)); + continue; + } + + std::unique_ptr result = factory(); + if (!result) + { + log("Unable to create handler", + entry("HANDLER=%s", ps.c_str())); + continue; + } + + manager->registerHandler(std::move(result)); } } -- cgit v1.2.3