summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2010-10-01 20:24:25 -0400
committerAdam <Adam@anope.org>2010-10-01 20:24:25 -0400
commit5d9df2bdc1bad51ec60bf6e64e27a01dd9336fa8 (patch)
tree3d4035026e4ad17bb21f96481277241356de911b
parent6ca09be66341fd9f568fb0ac754df4f4c561bc1f (diff)
Revert "Do not use new/delete to allocate modules, allows modules to always destruct properly and automatically"
This does not work as expected, it causes objects allocated by modules to be freed by the operating system when the module is unloaded, giving no chance to the module to deallocate it itself. This reverts commit 05e6815d912f0418f6da25a2106dd718796f02fa.
-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());