summaryrefslogtreecommitdiff
path: root/project2/basics
diff options
context:
space:
mode:
Diffstat (limited to 'project2/basics')
-rw-r--r--project2/basics/Jamfile.jam2
-rw-r--r--project2/basics/preload.cpp52
2 files changed, 54 insertions, 0 deletions
diff --git a/project2/basics/Jamfile.jam b/project2/basics/Jamfile.jam
index b276ba1..02de4c3 100644
--- a/project2/basics/Jamfile.jam
+++ b/project2/basics/Jamfile.jam
@@ -3,6 +3,7 @@ alias glibmm : : : :
<linkflags>"`pkg-config --libs glibmm-2.4`"
;
lib boost_filesystem : : <name>boost_filesystem ;
+lib dl ;
cpp-pch pch : pch.hpp :
<include>../../libmisc
@@ -16,6 +17,7 @@ lib p2basics :
<include>.
<include>../../libmisc
<library>glibmm
+ <library>dl
<library>boost_filesystem
<library>../common//p2common
;
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)
+