diff options
-rw-r--r-- | include/services.h | 25 | ||||
-rw-r--r-- | src/modulemanager.cpp | 18 |
2 files changed, 35 insertions, 8 deletions
diff --git a/include/services.h b/include/services.h index 95542c267..ae51653a0 100644 --- a/include/services.h +++ b/include/services.h @@ -140,26 +140,39 @@ extern "C" void __pfnBkCheck() {} /** This definition is used as shorthand for the various classes * and functions needed to make a module loadable by the OS. - * It defines the class factory and the external AnopeInit function. + * It defines the class factory and external AnopeInit and AnopeFini functions. */ #ifdef _WIN32 # define MODULE_INIT(x) \ extern "C" DllExport Module *AnopeInit(const Anope::string &, const Anope::string &); \ extern "C" Module *AnopeInit(const Anope::string &modname, const Anope::string &creator) \ { \ - static x module(modname, creator); \ - return &module; \ + return new x(modname, creator); \ } \ - BOOLEAN WINAPI DllMain(HINSTANCE, DWORD, LPVOID) \ + BOOLEAN WINAPI DllMain(HINSTANCE, DWORD nReason, LPVOID) \ { \ + switch (nReason) \ + { \ + case DLL_PROCESS_ATTACH: \ + case DLL_PROCESS_DETACH: \ + break; \ + } \ return TRUE; \ + } \ + extern "C" DllExport void AnopeFini(x *); \ + extern "C" void AnopeFini(x *m) \ + { \ + delete m; \ } #else # define MODULE_INIT(x) \ extern "C" DllExport Module *AnopeInit(const Anope::string &modname, const Anope::string &creator) \ { \ - static x module(modname, creator); \ - return &module; \ + return new x(modname, creator); \ + } \ + extern "C" DllExport void AnopeFini(x *m) \ + { \ + delete m; \ } #endif diff --git a/src/modulemanager.cpp b/src/modulemanager.cpp index 8ce75a849..d2dd6cd53 100644 --- a/src/modulemanager.cpp +++ b/src/modulemanager.cpp @@ -255,8 +255,22 @@ void ModuleManager::DeleteModule(Module *m) ano_module_t handle = m->handle; Anope::string filename = m->filename; - if (handle && dlclose(handle)) - Log() << ano_moderr(); + ano_modclearerr(); + void (*destroy_func)(Module *m) = function_cast<void (*)(Module *)>(dlsym(m->handle, "AnopeFini")); + const char *err = ano_moderr(); + if (!destroy_func && err && *err) + { + Log() << "No destroy function found, chancing delete..."; + delete m; /* we just have to chance they haven't overwrote the delete operator then... */ + } + else + destroy_func(m); /* Let the module delete it self, just in case */ + + if (handle) + { + if (dlclose(handle)) + Log() << ano_moderr(); + } if (!filename.empty()) DeleteFile(filename.c_str()); |