summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/services.h25
-rw-r--r--src/modulemanager.cpp18
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());