diff options
Diffstat (limited to 'project2/basics/preload.cpp')
-rw-r--r-- | project2/basics/preload.cpp | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/project2/basics/preload.cpp b/project2/basics/preload.cpp new file mode 100644 index 0000000..e8aa6e9 --- /dev/null +++ b/project2/basics/preload.cpp @@ -0,0 +1,52 @@ +#include <pch.hpp> +#include <options.h> +#include <boost/filesystem/path.hpp> +#include <map> +#include <dlfcn.h> + +using namespace boost::filesystem; + +class Preload { + public: + INITOPTIONS; + + private: + typedef boost::shared_ptr<void> Library; + typedef std::map<path, Library> Libraries; + + static void LoadLibrary(const VariableType & librarypath) + { + const auto beforeOpts = *Plugable::ComponentType<Options>::components(); + + void * handle = dlopen(librarypath, RTLD_NOW); + if (handle) { + Logger()->messagebf(LOG_DEBUG, "Loaded library '%s'", librarypath.as<std::string>()); + } + else { + Logger()->messagebf(LOG_ERR, "Failed to load library '%s' (%s)", librarypath.as<std::string>(), dlerror()); + throw std::runtime_error("module load failed"); + } + libs[librarypath.as<std::string>()] = boost::shared_ptr<void>(handle, &dlclose); + + const auto afterOpts = Plugable::ComponentType<Options>::components(); + BOOST_FOREACH(const auto & opt, *afterOpts) { + if (std::find(beforeOpts.begin(), beforeOpts.end(), opt) == beforeOpts.end()) { + opt->reset(); + } + } + } + + static void UnloadLibraries() + { + libs.clear(); + } + + static Libraries libs; +}; + +Preload::Libraries Preload::libs; + +DECLARE_OPTIONS(Preload, "Library preload options") +("library", Options::functions(Preload::LoadLibrary, Preload::UnloadLibraries), "Libraries to preload") +END_OPTIONS(Preload) + |