diff --git a/hpx/exception.hpp b/hpx/exception.hpp index 0f9ea4026581..bfe605e39306 100644 --- a/hpx/exception.hpp +++ b/hpx/exception.hpp @@ -93,6 +93,7 @@ namespace hpx duplicate_component_id = 46, ///< The component type has already been registered unknown_error = 47, ///< An unknown error occurred bad_plugin_type = 48, ///< The specified plugin type is not known or otherwise invalid + filesystem_error = 49, ///< The specified file does not exist or other filesystem related error /// \cond NOINTERNAL last_error, @@ -150,7 +151,9 @@ namespace hpx /* 44 */ "thread_interrupted", /* 45 */ "thread_not_interruptable", /* 46 */ "duplicate_component_id", - /* 47 */ "unknown_error" + /* 47 */ "unknown_error", + /* 48 */ "bad_plugin_type", + /* 49 */ "filesystem_error", /* */ "" }; /// \endcond diff --git a/hpx/runtime/components/server/runtime_support.hpp b/hpx/runtime/components/server/runtime_support.hpp index d3e8e90c5afa..81152107ad1e 100644 --- a/hpx/runtime/components/server/runtime_support.hpp +++ b/hpx/runtime/components/server/runtime_support.hpp @@ -295,9 +295,11 @@ namespace hpx { namespace components { namespace server boost::program_options::options_description& options, std::set& startup_handled); - bool load_startup_shutdown_functions(hpx::util::plugin::dll& d); + bool load_startup_shutdown_functions(hpx::util::plugin::dll& d, + error_code& ec); bool load_commandline_options(hpx::util::plugin::dll& d, - boost::program_options::options_description& options); + boost::program_options::options_description& options, + error_code& ec); // Load all plugins from the ini files found in the configuration bool load_plugins(util::section& ini); diff --git a/hpx/util/plugin/detail/dll_dlopen.hpp b/hpx/util/plugin/detail/dll_dlopen.hpp index bdcf52b1748f..9d2e19e52d13 100644 --- a/hpx/util/plugin/detail/dll_dlopen.hpp +++ b/hpx/util/plugin/detail/dll_dlopen.hpp @@ -22,6 +22,7 @@ #include #include +#include #include #if !defined(__ANDROID__) && !defined(ANDROID) && !defined(__APPLE__) @@ -124,15 +125,11 @@ namespace hpx { namespace util { namespace plugin { public: dll() : dll_handle (NULL) - { - LoadLibrary(); - } + {} dll(dll const& rhs) : dll_name(rhs.dll_name), map_name(rhs.map_name), dll_handle(NULL) - { - LoadLibrary(); - } + {} dll(std::string const& name) : dll_name(name), map_name(""), dll_handle(NULL) @@ -146,15 +143,16 @@ namespace hpx { namespace util { namespace plugin { fs::path dll_path(dll_name); #endif map_name = fs::basename(dll_path); + } - LoadLibrary(); + void load_library(error_code& ec = throws) + { + LoadLibrary(ec); } dll(std::string const& libname, std::string const& mapname) : dll_name(libname), map_name(mapname), dll_handle(NULL) - { - LoadLibrary(); - } + {} dll &operator=(dll const& rhs) { @@ -180,8 +178,11 @@ namespace hpx { namespace util { namespace plugin { template std::pair - get(std::string const& symbol_name) const + get(std::string const& symbol_name, error_code& ec = throws) const { + const_cast(*this).LoadLibrary(ec); // make sure everything is initialized + if (ec) return std::pair(); + initialize_mutex(); boost::mutex::scoped_lock lock(mutex_instance()); @@ -199,8 +200,10 @@ namespace hpx { namespace util { namespace plugin { str << "Hpx.Plugin: Could not open shared library '" << dll_name << "' (dlerror: " << dlerror() << ")"; - boost::throw_exception( - std::logic_error(HPX_PLUGIN_OSSTREAM_GETSTRING(str))); + // report error + HPX_THROWS_IF(ec, filesystem_error, + "plugin::get", HPX_PLUGIN_OSSTREAM_GETSTRING(str)); + return std::pair(); } #if !defined(__AIX__) @@ -225,55 +228,73 @@ namespace hpx { namespace util { namespace plugin { dlerror(); MyFreeLibrary(handle); - boost::throw_exception( - std::logic_error(HPX_PLUGIN_OSSTREAM_GETSTRING(str))); + + // report error + HPX_THROWS_IF(ec, filesystem_error, + "plugin::get", HPX_PLUGIN_OSSTREAM_GETSTRING(str)); + return std::pair(); } return std::make_pair(address, free_dll(handle)); } - void keep_alive() + void keep_alive(error_code& ec = throws) { - LoadLibrary(); + LoadLibrary(ec, true); } protected: - void LoadLibrary() + void LoadLibrary(error_code& ec = throws, bool force = false) { - initialize_mutex(); - boost::mutex::scoped_lock lock(mutex_instance()); + if (!dll_handle || force) + initialize_mutex(); + boost::mutex::scoped_lock lock(mutex_instance()); - ::dlerror(); // Clear the error state. - dll_handle = MyLoadLibrary((dll_name.empty() ? NULL : dll_name.c_str())); - // std::cout << "open\n"; - if (!dll_handle) { - HPX_PLUGIN_OSSTREAM str; - str << "Hpx.Plugin: Could not open shared library '" - << dll_name << "' (dlerror: " << dlerror() << ")"; - boost::throw_exception( - std::logic_error(HPX_PLUGIN_OSSTREAM_GETSTRING(str))); + ::dlerror(); // Clear the error state. + dll_handle = MyLoadLibrary((dll_name.empty() ? NULL : dll_name.c_str())); + // std::cout << "open\n"; + if (!dll_handle) { + HPX_PLUGIN_OSSTREAM str; + str << "Hpx.Plugin: Could not open shared library '" + << dll_name << "' (dlerror: " << dlerror() << ")"; + + HPX_THROWS_IF(ec, filesystem_error, + "plugin::LoadLibrary", HPX_PLUGIN_OSSTREAM_GETSTRING(str)); + return; + } + + init_library(dll_handle); // initialize library } - init_library(dll_handle); // initialize library + if (&ec != &throws) + ec = make_success_code(); } public: -#if !defined(__ANDROID__) && !defined(ANDROID) && !defined(__APPLE__) std::string get_directory() const { // now find the full path of the loaded library - char directory[PATH_MAX]; - if (::dlinfo(dll_handle, RTLD_DI_ORIGIN, directory) < 0) { + char directory[PATH_MAX] = { '\0' }; + +#if !defined(__ANDROID__) && !defined(ANDROID) && !defined(__APPLE__) + const_cast(*this).LoadLibrary(ec); + if (!ec && ::dlinfo(dll_handle, RTLD_DI_ORIGIN, directory) < 0) { HPX_PLUGIN_OSSTREAM str; str << "Hpx.Plugin: Could not extract path the shared " "library '" << dll_name << "' has been loaded from " "(dlerror: " << dlerror() << ")"; - boost::throw_exception( - std::logic_error(HPX_PLUGIN_OSSTREAM_GETSTRING(str))); + + HPX_THROWS_IF(ec, filesystem_error, + "plugin::get_directory", + HPX_PLUGIN_OSSTREAM_GETSTRING(str)); } ::dlerror(); // Clear the error state. +#endif + + if (&ec != &throws) + ec = make_success_code(); + return directory; } -#endif protected: void FreeLibrary() diff --git a/hpx/util/plugin/detail/dll_windows.hpp b/hpx/util/plugin/detail/dll_windows.hpp index e11ee53f8a2e..ea56296c9c0c 100644 --- a/hpx/util/plugin/detail/dll_windows.hpp +++ b/hpx/util/plugin/detail/dll_windows.hpp @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -54,15 +55,11 @@ namespace hpx { namespace util { namespace plugin { public: dll() : dll_handle(NULL) - { - LoadLibrary(); - } + {} dll(dll const& rhs) : dll_name(rhs.dll_name), map_name(rhs.map_name), dll_handle(NULL) - { - LoadLibrary(); - } + {} dll(std::string const& libname) : dll_name(libname), map_name(""), dll_handle(NULL) @@ -76,15 +73,16 @@ namespace hpx { namespace util { namespace plugin { fs::path dll_path(dll_name); #endif map_name = fs::basename(dll_path); + } - LoadLibrary(); + void load_library(error_code& ec = throws) + { + LoadLibrary(ec); } dll(std::string const& libname, std::string const& mapname) : dll_name(libname), map_name(mapname), dll_handle(NULL) - { - LoadLibrary(); - } + {} dll &operator=(dll const& rhs) { @@ -110,8 +108,11 @@ namespace hpx { namespace util { namespace plugin { template std::pair - get(std::string const& symbol_name) const + get(std::string const& symbol_name, error_code& ec = throws) const { + const_cast(*this).LoadLibrary(ec); // make sure everything is initialized + if (ec) return std::pair(); + BOOST_STATIC_ASSERT(boost::is_pointer::value); typedef typename boost::remove_pointer::type PointedType; @@ -125,8 +126,10 @@ namespace hpx { namespace util { namespace plugin { str << "Hpx.Plugin: Could not open shared library '" << dll_name << "'"; - boost::throw_exception( - std::logic_error(HPX_PLUGIN_OSSTREAM_GETSTRING(str))); + // report error + HPX_THROWS_IF(ec, filesystem_error, + "plugin::get", HPX_PLUGIN_OSSTREAM_GETSTRING(str)); + return std::pair(); } BOOST_ASSERT(handle == dll_handle); @@ -140,54 +143,76 @@ namespace hpx { namespace util { namespace plugin { << dll_name << "'"; ::FreeLibrary(handle); - boost::throw_exception( - std::logic_error(HPX_PLUGIN_OSSTREAM_GETSTRING(str))); + + // report error + HPX_THROWS_IF(ec, filesystem_error, + "plugin::get", HPX_PLUGIN_OSSTREAM_GETSTRING(str)); + return std::pair(); } return std::make_pair(address, detail::free_dll(handle)); } - void keep_alive() + void keep_alive(error_code& ec = throws) { - LoadLibrary(); + LoadLibrary(ec, true); } protected: - void LoadLibrary() + void LoadLibrary(error_code& ec = throws, bool force = false) { - if (dll_name.empty()) { - // load main module - char buffer[_MAX_PATH]; - ::GetModuleFileName(NULL, buffer, sizeof(buffer)); - dll_name = buffer; + if (!dll_handle || force) + { + if (dll_name.empty()) { + // load main module + char buffer[_MAX_PATH]; + ::GetModuleFileName(NULL, buffer, sizeof(buffer)); + dll_name = buffer; + } + + dll_handle = ::LoadLibrary(dll_name.c_str()); + if (!dll_handle) { + HPX_PLUGIN_OSSTREAM str; + str << "Hpx.Plugin: Could not open shared library '" + << dll_name << "'"; + + HPX_THROWS_IF(ec, filesystem_error, + "plugin::LoadLibrary", + HPX_PLUGIN_OSSTREAM_GETSTRING(str)); + return; + } } - dll_handle = ::LoadLibrary(dll_name.c_str()); - if (!dll_handle) { - HPX_PLUGIN_OSSTREAM str; - str << "Hpx.Plugin: Could not open shared library '" - << dll_name << "'"; - - boost::throw_exception( - std::logic_error(HPX_PLUGIN_OSSTREAM_GETSTRING(str))); - } + if (&ec != &throws) + ec = make_success_code(); } public: - std::string get_directory() const + std::string get_directory(error_code& ec = throws) const { - char buffer[_MAX_PATH]; + char buffer[_MAX_PATH] = { '\0' }; + + const_cast(*this).LoadLibrary(ec); // make sure everything is initialized + if (ec) return buffer; + DWORD name_length = GetModuleFileName(dll_handle, buffer, sizeof(buffer)); + if (name_length <= 0) { HPX_PLUGIN_OSSTREAM str; str << "Hpx.Plugin: Could not extract path the shared " "library '" << dll_name << "' has been loaded from."; - boost::throw_exception( - std::logic_error(HPX_PLUGIN_OSSTREAM_GETSTRING(str))); + + HPX_THROWS_IF(ec, filesystem_error, + "plugin::get_directory", HPX_PLUGIN_OSSTREAM_GETSTRING(str)); + return buffer; } // extract the directory name PathRemoveFileSpec(buffer); + + if (&ec != &throws) + ec = make_success_code(); + return buffer; } diff --git a/hpx/util/plugin/detail/plugin_factory_impl.hpp b/hpx/util/plugin/detail/plugin_factory_impl.hpp index f49d231d021e..2a596933cc38 100644 --- a/hpx/util/plugin/detail/plugin_factory_impl.hpp +++ b/hpx/util/plugin/detail/plugin_factory_impl.hpp @@ -53,6 +53,16 @@ namespace detail { get_abstract_factory(this->m_dll, name, this->m_basename); return r.first->create(r.second, BOOST_PP_ENUM_PARAMS(N, a)); } + + BasePlugin* create(std::string const& name, error_code& ec, + BOOST_PP_ENUM_BINARY_PARAMS(N, A, a)) + { + std::pair *, dll_handle> r = + get_abstract_factory(this->m_dll, name, this->m_basename, ec); + if (ec) return 0; + + return r.first->create(r.second, BOOST_PP_ENUM_PARAMS(N, a)); + } }; /////////////////////////////////////////////////////////////////////////// @@ -74,6 +84,17 @@ namespace detail { this->f, &empty_deleter, name); return r.first->create(r.second, BOOST_PP_ENUM_PARAMS(N, a)); } + + BasePlugin* create(std::string const& name, error_code& ec, + BOOST_PP_ENUM_BINARY_PARAMS(N, A, a)) + { + std::pair *, dll_handle> r = + get_abstract_factory_static( + this->f, &empty_deleter, name, ec); + if (ec) return 0; + + return r.first->create(r.second, BOOST_PP_ENUM_PARAMS(N, a)); + } }; /////////////////////////////////////////////////////////////////////////////// diff --git a/hpx/util/plugin/plugin_factory.hpp b/hpx/util/plugin/plugin_factory.hpp index cef6d2f2aae5..952ca47ac2bc 100644 --- a/hpx/util/plugin/plugin_factory.hpp +++ b/hpx/util/plugin/plugin_factory.hpp @@ -23,6 +23,8 @@ #include #include +#include + namespace hpx { namespace util { namespace plugin { /////////////////////////////////////////////////////////////////////////// @@ -31,7 +33,8 @@ namespace hpx { namespace util { namespace plugin { template std::pair *, dll_handle> get_abstract_factory_static(get_plugins_list_type f, DeleterType d, - std::string const &class_name, std::string const& libname = "") + std::string const &class_name, std::string const& libname = "", + error_code& ec = throws) { typedef typename boost::remove_pointer::type PointedType; @@ -45,7 +48,10 @@ namespace hpx { namespace util { namespace plugin { boost::unsafe_any_cast *>(&(*it).second); if (!xw) { - throw std::logic_error("Hpx.Plugin: Can't cast to the right factory type\n"); + HPX_THROWS_IF(ec, filesystem_error, + "get_abstract_factory_static", + "Hpx.Plugin: Can't cast to the right factory type\n"); + return std::pair *, dll_handle>(); } abstract_factory *w = *xw; @@ -81,14 +87,17 @@ namespace hpx { namespace util { namespace plugin { str << " No classes exist."; } - throw std::logic_error(HPX_PLUGIN_OSSTREAM_GETSTRING(str)); + HPX_THROWS_IF(ec, filesystem_error, + "get_abstract_factory_static", + HPX_PLUGIN_OSSTREAM_GETSTRING(str)); + return std::pair *, dll_handle>(); } } template std::pair *, dll_handle> get_abstract_factory(dll const& d, std::string const &class_name, - std::string const &base_name) + std::string const &base_name, error_code& ec = throws) { typedef boost::function DeleterType; @@ -98,15 +107,16 @@ namespace hpx { namespace util { namespace plugin { plugin_entry += "_" + base_name; std::pair f = - d.get(plugin_entry); + d.get(plugin_entry, ec); + if (ec) return std::pair *, dll_handle>(); return get_abstract_factory_static(f.first, f.second, - class_name, d.get_name()); + class_name, d.get_name(), ec); } inline void get_abstract_factory_names(dll const& d, std::string const &base_name, - std::vector& names) + std::vector& names, error_code& ec = throws) { typedef boost::function DeleterType; @@ -116,7 +126,8 @@ namespace hpx { namespace util { namespace plugin { plugin_entry += "_" + base_name; std::pair f = - d.get(plugin_entry); + d.get(plugin_entry, ec); + if (ec) return; exported_plugins_type& e = (f.first)(); @@ -132,9 +143,9 @@ namespace hpx { namespace util { namespace plugin { { void create(int******) const; - void get_names(std::vector& names) const + void get_names(std::vector& names, error_code& ec = throws) const { - get_abstract_factory_names(this->m_dll, this->m_basename, names); + get_abstract_factory_names(this->m_dll, this->m_basename, names, ec); } protected: @@ -150,10 +161,12 @@ namespace hpx { namespace util { namespace plugin { struct plugin_factory_item > : public Base { - BasePlugin* create(std::string const& name) const + BasePlugin* create(std::string const& name, error_code& ec = throws) const { std::pair *, dll_handle> r = - get_abstract_factory(this->m_dll, name, this->m_basename); + get_abstract_factory(this->m_dll, name, this->m_basename, ec); + if (ec) return 0; + return r.first->create(r.second); } }; @@ -169,6 +182,15 @@ namespace hpx { namespace util { namespace plugin { get_abstract_factory(this->m_dll, name, this->m_basename); return r.first->create(r.second, a1); } + + BasePlugin* create(std::string const& name, error_code& ec, A1 a1) const + { + std::pair *, dll_handle> r = + get_abstract_factory(this->m_dll, name, this->m_basename, ec); + if (ec) return 0; + + return r.first->create(r.second, a1); + } }; template @@ -182,6 +204,15 @@ namespace hpx { namespace util { namespace plugin { get_abstract_factory(this->m_dll, name, this->m_basename); return r.first->create(r.second, a1, a2); } + + BasePlugin* create(std::string const& name, error_code& ec, A1 a1, A2 a2) const + { + std::pair *, dll_handle> r = + get_abstract_factory(this->m_dll, name, this->m_basename, ec); + if (ec) return 0; + + return r.first->create(r.second, a1, a2); + } }; /////////////////////////////////////////////////////////////////////// @@ -206,11 +237,13 @@ namespace hpx { namespace util { namespace plugin { struct static_plugin_factory_item > : public Base { - BasePlugin* create(std::string const& name) const + BasePlugin* create(std::string const& name, error_code& ec = throws) const { std::pair *, dll_handle> r = get_abstract_factory_static( - this->f, &empty_deleter, name); + this->f, &empty_deleter, name, ec); + if (ec) return 0; + return r.first->create(r.second); } }; @@ -227,6 +260,17 @@ namespace hpx { namespace util { namespace plugin { this->f, &empty_deleter, name); return r.first->create(r.second, a1); } + + using Base::create; + BasePlugin* create(std::string const& name, error_code& ec, A1 a1) const + { + std::pair *, dll_handle> r = + get_abstract_factory_static( + this->f, &empty_deleter, name, ec); + if (ec) return 0; + + return r.first->create(r.second, a1); + } }; template @@ -241,6 +285,16 @@ namespace hpx { namespace util { namespace plugin { this->f, &empty_deleter, name); return r.first->create(r.second, a1, a2); } + + BasePlugin* create(std::string const& name, error_code& ec, A1 a1, A2 a2) const + { + std::pair *, dll_handle> r = + get_abstract_factory_static( + this->f, &empty_deleter, name, ec); + if (ec) return 0; + + return r.first->create(r.second, a1, a2); + } }; } diff --git a/src/runtime/components/server/runtime_support.cpp b/src/runtime/components/server/runtime_support.cpp index 4852c2141e79..db12754787a3 100644 --- a/src/runtime/components/server/runtime_support.cpp +++ b/src/runtime/components/server/runtime_support.cpp @@ -757,7 +757,7 @@ namespace hpx { namespace components { namespace server pp, num_messages, interval); if (0 == mh) { hpx::util::osstream strm; - strm << "couldn't to create message handler plugin of type: " + strm << "couldn't to create message handler plugin of type: " << message_handler_type; HPX_THROWS_IF(ec, hpx::bad_plugin_type, "runtime_support::create_message_handler", @@ -805,7 +805,7 @@ namespace hpx { namespace components { namespace server util::binary_filter* bf = factory->create(compress); if (0 == bf) { hpx::util::osstream strm; - strm << "couldn't to create binary filter plugin of type: " + strm << "couldn't to create binary filter plugin of type: " << binary_filter_type; HPX_THROWS_IF(ec, hpx::bad_plugin_type, "runtime_support::create_binary_filter", @@ -998,7 +998,8 @@ namespace hpx { namespace components { namespace server } /////////////////////////////////////////////////////////////////////////// - bool runtime_support::load_startup_shutdown_functions(hpx::util::plugin::dll& d) + bool runtime_support::load_startup_shutdown_functions(hpx::util::plugin::dll& d, + error_code& ec) { try { // get the factory, may fail @@ -1007,7 +1008,12 @@ namespace hpx { namespace components { namespace server // create the startup_shutdown object boost::shared_ptr - startup_shutdown(pf.create("startup_shutdown")); + startup_shutdown(pf.create("startup_shutdown", ec)); + if (ec) { + LRT_(debug) << "loading of command-line options failed: " + << d.get_name() << ": " << get_error_what(ec); + return false; + } startup_function_type startup; bool pre_startup = true; @@ -1047,7 +1053,7 @@ namespace hpx { namespace components { namespace server /////////////////////////////////////////////////////////////////////////// bool runtime_support::load_commandline_options(hpx::util::plugin::dll& d, - boost::program_options::options_description& options) + boost::program_options::options_description& options, error_code& ec) { try { // get the factory, may fail @@ -1056,7 +1062,12 @@ namespace hpx { namespace components { namespace server // create the startup_shutdown object boost::shared_ptr - commandline_options(pf.create("commandline_options")); + commandline_options(pf.create("commandline_options", ec)); + if (ec) { + LRT_(debug) << "loading of command-line options failed: " + << d.get_name() << ": " << get_error_what(ec); + return false; + } options.add(commandline_options->add_commandline_options()); } @@ -1093,8 +1104,16 @@ namespace hpx { namespace components { namespace server try { // get the handle of the library + error_code ec; hpx::util::plugin::dll d(lib.string(), HPX_MANGLE_STRING(component)); + d.load_library(ec); + if (ec) { + LRT_(warning) << "dynamic loading failed: " << lib.string() + << ": " << instance << ": " << get_error_what(ec); + return false; + } + // initialize the factory instance using the preferences from the // ini files util::section const* glob_ini = NULL; @@ -1114,7 +1133,12 @@ namespace hpx { namespace components { namespace server // create the component factory object, if not disabled boost::shared_ptr factory ( - pf.create(instance, glob_ini, component_ini, isenabled)); + pf.create(instance, ec, glob_ini, component_ini, isenabled)); + if (ec) { + LRT_(warning) << "dynamic loading failed: " << lib.string() + << ": " << instance << ": " << get_error_what(ec); + return false; + } component_type t = factory->get_component_type( prefix, agas_client); @@ -1156,8 +1180,8 @@ namespace hpx { namespace components { namespace server // module, same for plugins if (startup_handled.find(d.get_name()) == startup_handled.end()) { startup_handled.insert(d.get_name()); - load_commandline_options(d, options); - load_startup_shutdown_functions(d); + load_commandline_options(d, options, ec); + load_startup_shutdown_functions(d, ec); } } catch (hpx::exception const&) { @@ -1270,8 +1294,16 @@ namespace hpx { namespace components { namespace server try { // get the handle of the library + error_code ec; hpx::util::plugin::dll d(lib.string(), HPX_MANGLE_STRING(plugin)); + d.load_library(ec); + if (ec) { + LRT_(warning) << "dynamic loading failed: " << lib.string() + << ": " << instance << ": " << get_error_what(ec); + return false; + } + // initialize the factory instance using the preferences from the // ini files util::section const* glob_ini = NULL; @@ -1292,7 +1324,12 @@ namespace hpx { namespace components { namespace server // create the component factory object, if not disabled boost::shared_ptr factory ( - pf.create(instance, glob_ini, plugin_ini, isenabled)); + pf.create(instance, ec, glob_ini, plugin_ini, isenabled)); + if (ec) { + LRT_(warning) << "dynamic loading failed: " << lib.string() + << ": " << instance << ": " << get_error_what(ec); + return false; + } // store component factory and module for later use plugin_factory_type data(factory, d, isenabled); diff --git a/src/util/find_prefix.cpp b/src/util/find_prefix.cpp index 5759490aefdf..72b891e4954c 100644 --- a/src/util/find_prefix.cpp +++ b/src/util/find_prefix.cpp @@ -34,14 +34,18 @@ namespace hpx { namespace util { #if !defined(__ANDROID__) && !defined(ANDROID) && !defined(__APPLE__) && !defined(__MIC) try { + error_code ec; hpx::util::plugin::dll dll(HPX_MAKE_DLL_STRING(library)); + d.load_library(ec); + if (ec) return HPX_PREFIX; + using boost::filesystem::path; std::string const prefix = - path(dll.get_directory()).parent_path().parent_path().string(); + path(dll.get_directory(ec)).parent_path().parent_path().string(); - if (prefix.empty()) + if (ec || prefix.empty()) return HPX_PREFIX; return prefix; diff --git a/src/util/init_ini_data.cpp b/src/util/init_ini_data.cpp index 7ba5a54a63c6..3fa8212f6cf4 100644 --- a/src/util/init_ini_data.cpp +++ b/src/util/init_ini_data.cpp @@ -180,14 +180,15 @@ namespace hpx { namespace util // iterate over all shared libraries in the given directory and construct // default ini settings assuming all of those are components void load_component_factory(hpx::util::plugin::dll& d, util::section& ini, - std::string const& curr, std::string name) + std::string const& curr, std::string name, error_code& ec) { hpx::util::plugin::plugin_factory pf(d, "registry"); // retrieve the names of all known registries std::vector names; - pf.get_names(names); // throws on error + pf.get_names(names, ec); + if (ec) return; std::vector ini_data; if (names.empty()) { @@ -212,7 +213,9 @@ namespace hpx { namespace util { // create the component registry object boost::shared_ptr - registry (pf.create(s)); + registry (pf.create(s, ec)); + if (ec) return; + registry->get_component_info(ini_data); } } @@ -223,14 +226,15 @@ namespace hpx { namespace util } void load_plugin_factory(hpx::util::plugin::dll& d, util::section& ini, - std::string const& curr, std::string const& name) + std::string const& curr, std::string const& name, error_code& ec) { hpx::util::plugin::plugin_factory pf(d, "plugin"); // retrieve the names of all known registries std::vector names; - pf.get_names(names); // throws on error + pf.get_names(names, ec); // throws on error + if (ec) return; std::vector ini_data; if (!names.empty()) { @@ -239,7 +243,9 @@ namespace hpx { namespace util { // create the plugin registry object boost::shared_ptr - registry(pf.create(s)); + registry(pf.create(s, ec)); + if (ec) return; + registry->get_plugin_info(ini_data); } } @@ -289,14 +295,21 @@ namespace hpx { namespace util if (0 == name.find("lib")) name = name.substr(3); #endif - try { // get the handle of the library + error_code ec; hpx::util::plugin::dll d(curr.string(), name); - // get the component factory - std::string curr_fullname(curr.parent_path().string()); - load_component_factory(d, ini, curr_fullname, name); + d.load_library(ec); + if (!ec) { + // get the component factory + std::string curr_fullname(curr.parent_path().string()); + load_component_factory(d, ini, curr_fullname, name, ec); + } + if (ec) { + LRT_(info) << "skipping " << curr.string() + << ": " << get_error_what(ec); + } } catch (std::logic_error const& e) { LRT_(info) << "skipping " << curr.string() @@ -306,14 +319,26 @@ namespace hpx { namespace util LRT_(info) << "skipping " << curr.string() << ": " << e.what(); } + catch (...) { + LRT_(info) << "skipping " << curr.string() + << ": unexpected exception"; + } try { // get the handle of the library + error_code ec; hpx::util::plugin::dll d(curr.string(), name); - // get the component factory - std::string curr_fullname(curr.parent_path().string()); - load_plugin_factory(d, ini, curr_fullname, name); + d.load_library(ec); + if (!ec) { + // get the component factory + std::string curr_fullname(curr.parent_path().string()); + load_plugin_factory(d, ini, curr_fullname, name, ec); + } + if (ec) { + LRT_(info) << "skipping " << curr.string() + << ": " << get_error_what(ec); + } } catch (std::logic_error const& e) { LRT_(info) << "skipping " << curr.string() @@ -323,6 +348,10 @@ namespace hpx { namespace util LRT_(info) << "skipping " << curr.string() << ": " << e.what(); } + catch (...) { + LRT_(info) << "skipping " << curr.string() + << ": unexpected exception"; + } } } catch (fs::filesystem_error const& /*e*/) {