summaryrefslogtreecommitdiff
path: root/project2/basics/preload.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'project2/basics/preload.cpp')
-rw-r--r--project2/basics/preload.cpp52
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)
+