- plugins are now loaded as RTLD_GLOBALmaster
@@ -21,6 +21,10 @@ namespace booster { | |||
/// | |||
class BOOSTER_API shared_object : public booster::noncopyable { | |||
public: | |||
static const int load_lazy = 1; /// Pass RTLD_LAZY to dlopen | |||
static const int load_now = 2; /// Pass RTLD_NOW to dlopen | |||
static const int load_global = 3; /// Pass RTLD_GLOBAL to dlopen | |||
static const int load_local = 4; /// Pass RTLD_LOCAL to dlopen | |||
/// | |||
/// Create an empty shared object | |||
/// | |||
@@ -34,6 +38,15 @@ namespace booster { | |||
/// Create shared object and load it, \see open(std::string const&,bool); | |||
/// | |||
/// \param file_name - the name of the file, UTF-8 encoded under Windows | |||
/// \params flags - load flags: one of load_lazy, load_now, load_local, load_global - ignored on Windows | |||
/// | |||
/// \throws booster::system::system_error if it is impossible to load it | |||
/// \ver{v1_2} | |||
shared_object(std::string const &file_name,int flags); | |||
/// | |||
/// Create shared object and load it, \see open(std::string const&,bool); | |||
/// | |||
/// \param file_name - the name of the file, UTF-8 encoded under Windows | |||
/// | |||
/// \throws booster::system::system_error if it is impossible to load it | |||
/// | |||
@@ -58,6 +71,26 @@ namespace booster { | |||
/// | |||
bool open(std::string const &file_name,std::string &error_message); | |||
/// | |||
/// Load shared object or dll | |||
/// | |||
/// \param file_name - the name of the file, UTF-8 encoded under Windows | |||
/// \params flags - load flags: one of load_lazy, load_now, load_local, load_global - ignored on Windows | |||
/// \return true if the shared object was loaded | |||
/// | |||
/// \ver{v1_2} | |||
bool open(std::string const &file_name,int flags); | |||
/// | |||
/// Load shared object or dll | |||
/// | |||
/// \param file_name - the name of the file, UTF-8 encoded under Windows | |||
/// \params flags - load flags: one of load_lazy, load_now, load_local, load_global - ignored on Windows | |||
/// \param error_message - the error message | |||
/// \return true if the shared object was loaded | |||
/// | |||
/// \ver{v1_2} | |||
bool open(std::string const &file_name,std::string &error_message,int flags); | |||
/// | |||
/// | |||
/// Unload the shared object | |||
/// | |||
void close(); | |||
@@ -28,6 +28,13 @@ namespace booster { | |||
shared_object::~shared_object() | |||
{ | |||
} | |||
shared_object::shared_object(std::string const &name,int) : d(new data()) | |||
{ | |||
std::string err; | |||
if(!open(name,err)) { | |||
throw booster::runtime_error("booster::shared_object: failed to load shared library " + name +": " + err); | |||
} | |||
} | |||
shared_object::shared_object(std::string const &name) : d(new data()) | |||
{ | |||
std::string err; | |||
@@ -46,12 +53,20 @@ namespace booster { | |||
{ | |||
return d->handle != 0; | |||
} | |||
bool shared_object::open(std::string const &file_name,int) | |||
{ | |||
return open(file_name); | |||
} | |||
bool shared_object::open(std::string const &file_name) | |||
{ | |||
close(); | |||
d->handle = LoadLibraryW(booster::nowide::convert(file_name).c_str()); | |||
return d->handle != 0; | |||
} | |||
bool shared_object::open(std::string const &file_name,std::string &error_message,int) | |||
{ | |||
return open(file_name,error_message); | |||
} | |||
bool shared_object::open(std::string const &file_name,std::string &error_message) | |||
{ | |||
if(open(file_name)) | |||
@@ -82,6 +97,13 @@ namespace booster { | |||
shared_object::~shared_object() | |||
{ | |||
} | |||
shared_object::shared_object(std::string const &name,int flags) : d(new data()) | |||
{ | |||
std::string err; | |||
if(!open(name,err,flags)) { | |||
throw booster::runtime_error("booster::shared_object: failed to load shared library " + name +": " + err); | |||
} | |||
} | |||
shared_object::shared_object(std::string const &name) : d(new data()) | |||
{ | |||
std::string err; | |||
@@ -102,14 +124,30 @@ namespace booster { | |||
} | |||
bool shared_object::open(std::string const &file_name) | |||
{ | |||
close(); | |||
d->handle = dlopen(file_name.c_str(),RTLD_LAZY); | |||
return d->handle != 0; | |||
return open(file_name,load_lazy); | |||
} | |||
bool shared_object::open(std::string const &file_name,int flags) | |||
{ | |||
std::string msg; | |||
return open(file_name,msg,flags); | |||
} | |||
bool shared_object::open(std::string const &file_name,std::string &error_message) | |||
{ | |||
return open(file_name,error_message,load_lazy); | |||
} | |||
bool shared_object::open(std::string const &file_name,std::string &error_message,int flags) | |||
{ | |||
close(); | |||
d->handle = dlopen(file_name.c_str(),RTLD_LAZY); | |||
int dlflags = 0; | |||
if(flags & load_lazy) | |||
dlflags |= RTLD_LAZY; | |||
if(flags & load_now) | |||
dlflags |= RTLD_NOW; | |||
if(flags & load_global) | |||
dlflags |= RTLD_GLOBAL; | |||
if(flags & load_local) | |||
dlflags |= RTLD_LOCAL; | |||
d->handle = dlopen(file_name.c_str(),flags); | |||
if(!d->handle) { | |||
error_message = dlerror(); | |||
return false; | |||
@@ -227,8 +227,9 @@ void scope::load(std::string const &name) | |||
so_name = (booster::locale::format(d->pattern) % name).str(std::locale::classic()); | |||
booster::shared_ptr<booster::shared_object> obj(new booster::shared_object()); | |||
int dlflags = booster::shared_object::load_lazy | booster::shared_object::load_global; | |||
if(d->paths.empty()) { | |||
if(!obj->open(so_name)) | |||
if(!obj->open(so_name,dlflags)) | |||
throw cppcms_error("Failed to load " + so_name); | |||
} | |||
else { | |||
@@ -238,7 +239,7 @@ void scope::load(std::string const &name) | |||
path = so_name; | |||
else | |||
path = path + "/" + so_name; | |||
if(obj->open(so_name)) | |||
if(obj->open(so_name,dlflags)) | |||
break; | |||
} | |||
if(!obj->is_open()) { | |||
@@ -271,7 +271,7 @@ namespace impl { | |||
shared_object(std::string file_name,bool /*unused*/) | |||
{ | |||
handler_ = dlopen(file_name.c_str(),RTLD_LAZY); | |||
handler_ = dlopen(file_name.c_str(),RTLD_LAZY | RTLD_GLOBAL); | |||
if(!handler_) { | |||
booster::system::error_code e(errno,booster::system::system_category); | |||
throw booster::system::system_error(e,"Failed to load library "+file_name); | |||