diff --git a/include/ircd/mapi.h b/include/ircd/mapi.h index e41642b68..33ff4468f 100644 --- a/include/ircd/mapi.h +++ b/include/ircd/mapi.h @@ -110,14 +110,7 @@ inline header::~header() noexcept { - if(ircd::main_exited) - { - // When central IRCd thinks this module is already unloaded when at this point, - // the DSO got stuck. This will not assert, but warn the developer to fix it. - const auto &name(meta["name"]); - log::warning("Module \"%s\" is stuck and failing to unload.", name.c_str()); - log::warning("Module \"%s\" may result in undefined behavior if not fixed.", name.c_str()); - } + mods::static_destruction = true; } const char *const diff --git a/include/ircd/modules.h b/include/ircd/modules.h index b0f3e39c4..16fe772e4 100644 --- a/include/ircd/modules.h +++ b/include/ircd/modules.h @@ -62,8 +62,6 @@ const std::string &desc(const mod &); std::string location(const mod &); std::string name(const mod &); -extern struct log::log log; - // Symbol handlers struct type_handlers { @@ -121,6 +119,9 @@ bool load(const std::string &name); void autoload(); void unload(); +extern struct log::log log; +extern bool static_destruction; + // Initialization and destruction singleton held by ircd::main() struct init { diff --git a/ircd/modules.cc b/ircd/modules.cc index 090cc39dc..b45042f92 100644 --- a/ircd/modules.cc +++ b/ircd/modules.cc @@ -199,6 +199,12 @@ catch(const std::exception &e) throw; } +// Allows module to communicate static destruction is taking place when mapi::header +// destructs. This allows us to gauge if the module *really* unloaded on command. DSO's +// are allowed to silently refuse to unload for any reason. We prefer developers to do +// things that don't trigger such behavior and allow a clean unload. +bool ircd::mods::static_destruction; + bool ircd::mods::unload(const std::string name) { @@ -215,8 +221,17 @@ ircd::mods::unload(const std::string name) unload_symbol(mod, name, sym.type); } + static_destruction = false; mods.erase(it); - log.info("Module '%s' unloaded", filename.c_str()); + + if(!static_destruction) + { + log.error("Module \"%s\" is stuck and failing to unload.", name.c_str()); + log.warning("Module \"%s\" may result in undefined behavior if not fixed.", name.c_str()); + } else { + log.info("Module '%s' unloaded", filename.c_str()); + } + return true; }