1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
#include <pch.hpp>
#include <options.h>
#include <library.h>
#include <appInstance.h>
#include <boost/filesystem/path.hpp>
#include <map>
#include <dlfcn.h>
#include <logger.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 = AdHoc::PluginManager::getDefault()->getAll<Options>();
void * handle = dlopen(librarypath, RTLD_GLOBAL | RTLD_NOW);
if (handle) {
Logger()->messagebf(LOG_DEBUG, "Loaded library '%s'", librarypath.as<std::string>());
}
else {
const char * dlerr = dlerror();
Logger()->messagebf(LOG_ERR, "Failed to load library '%s' (%s)", librarypath.as<std::string>(), dlerr);
throw LoadLibraryFailed(librarypath, dlerr);
}
libs[librarypath.as<std::string>()] = boost::shared_ptr<void>(handle, &dlclose);
const auto afterOpts = AdHoc::PluginManager::getDefault()->getAll<Options>();
for (const auto & opt : afterOpts) {
if (std::find(beforeOpts.begin(), beforeOpts.end(), opt) == beforeOpts.end()) {
opt->implementation()->reset();
}
}
}
static void UnloadLibraries()
{
AppInstance::current().clearScriptCache();
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)
|