summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrobbeh <robbeh@5417fbe8-f217-4b02-8779-1006273d7864>2008-11-15 21:25:40 +0000
committerrobbeh <robbeh@5417fbe8-f217-4b02-8779-1006273d7864>2008-11-15 21:25:40 +0000
commit2d768eb325fc7665093faedf62e08dd5f98cc5f8 (patch)
tree9345b8c524d6c65f2c2a2f92e0ce5bb70194b822
parentf0fe5427ff22c005220b0189ed745a38314dc21b (diff)
Modules now delete themselves instead of letting the core do it (just incase one of them has used a custom delete operator)
git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@1729 5417fbe8-f217-4b02-8779-1006273d7864
-rw-r--r--Changes1
-rw-r--r--include/modules.h11
-rw-r--r--include/services.h10
-rw-r--r--src/module.cpp6
-rw-r--r--src/modulemanager.cpp40
5 files changed, 54 insertions, 14 deletions
diff --git a/Changes b/Changes
index f92e0fe5c..76b9c75ad 100644
--- a/Changes
+++ b/Changes
@@ -6,3 +6,4 @@ Anope Version 1.9.0
10/12 F Move BotInfo and related methods into a class
11/01 F Move modules into a class
11/15 F Fixed ns resending of passcode issue
+11/15 F Modules now delete themselves \ No newline at end of file
diff --git a/include/modules.h b/include/modules.h
index c09b234c2..9e2889646 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -259,7 +259,7 @@ CoreExport class Module
* @return returns MOD_ERR_OK on success
*/
int DelCommand(CommandHash * cmdTable[], const char *name);
-
+
/**
* Adds a timed callback for the current module.
* This allows modules to request that anope executes one of there functions at a time in the future, without an event to trigger it
@@ -272,7 +272,7 @@ CoreExport class Module
* @see moduleDelCallBack
**/
int AddCallback(const char *name, time_t when, int (*func) (int argc, char *argv[]), int argc, char **argv);
-
+
/**
* Allow modules to delete a timed callback by name.
* @param name the name of the callback they wish to delete
@@ -307,10 +307,15 @@ CoreExport class ModuleManager
* @return MOD_ERR_OK on success, anything else on fail
*/
static int UnloadModule(Module *m, User * u);
-
+
/** Run all pending module timer callbacks.
*/
static void RunCallbacks();
+private:
+ /** Call the module_delete function to safely delete the module
+ * @param m the module to delete
+ */
+ static void DeleteModule(Module *m);
};
diff --git a/include/services.h b/include/services.h
index 70aaf0066..af5b524c5 100644
--- a/include/services.h
+++ b/include/services.h
@@ -202,16 +202,24 @@ extern int strncasecmp(const char *, const char *, size_t);
break; \
} \
return TRUE; \
+ } \
+ extern "C" DllExport void *destroy_module(y *m) \
+ { \
+ delete m; \
}
+
#else
#define MODULE_INIT(x, y) \
extern "C" DllExport Module *init_module(const std::string &modname, const std::string &creator) \
{ \
return new y(x, creator); \
+ } \
+ extern "C" DllExport void destroy_module(y *m) \
+ { \
+ delete m; \
}
#endif
-
/* Miscellaneous definitions. */
#include "defs.h"
#include "slist.h"
diff --git a/src/module.cpp b/src/module.cpp
index d0929bfdd..de72c7f64 100644
--- a/src/module.cpp
+++ b/src/module.cpp
@@ -69,12 +69,6 @@ Module::~Module()
remove(this->filename.c_str());
- if (this->handle)
- {
- if ((ano_modclose(this->handle)) != 0)
- alog("%s", ano_moderr());
- }
-
int idx;
CommandHash *current = NULL;
EvtHookHash *ehcurrent = NULL;
diff --git a/src/modulemanager.cpp b/src/modulemanager.cpp
index c248817bc..4f478c946 100644
--- a/src/modulemanager.cpp
+++ b/src/modulemanager.cpp
@@ -93,7 +93,7 @@ static bool IsOneOfModuleTypeLoaded(MODType mt)
int idx = 0;
ModuleHash *current = NULL;
int pmods = 0;
-
+
for (idx = 0; idx != MAX_CMD_HASH; idx++)
{
for (current = MODULE_HASH[idx]; current; current = current->next)
@@ -201,13 +201,13 @@ int ModuleManager::LoadModule(const std::string &modname, User * u)
if (m->type == PROTOCOL && IsOneOfModuleTypeLoaded(PROTOCOL))
{
- delete m;
+ DeleteModule(m);
alog("You cannot load two protocol modules");
return MOD_STOP;
}
else if (m->type == ENCRYPTION && IsOneOfModuleTypeLoaded(ENCRYPTION))
{
- delete m;
+ DeleteModule(m);
alog("You cannot load two encryption modules");
return MOD_STOP;
}
@@ -245,6 +245,38 @@ int ModuleManager::UnloadModule(Module *m, User *u)
notice_lang(s_OperServ, u, OPER_MODULE_UNLOADED, m->name.c_str());
}
- delete m;
+ DeleteModule(m);
return MOD_ERR_OK;
}
+
+void ModuleManager::DeleteModule(Module *m)
+{
+ const char *err;
+ void (*destroy_func)(Module *m);
+ void *handle;
+
+ if (!m || !m->handle) /* check m is least possibly valid */
+ {
+ return;
+ }
+
+ handle = m->handle;
+
+ ano_modclearerr();
+ destroy_func = (void(*)(Module *m))ano_modsym(m->handle, "destroy_module");
+ if (destroy_func == NULL && (err = ano_moderr()) != NULL)
+ {
+ alog("No magical destroy function found, chancing delete...");
+ delete m; /* we just have to change they haven't overwrote the delete operator then... */
+ }
+ else
+ {
+ destroy_func(m); /* Let the module delete it self, just in case */
+ }
+
+ if (handle)
+ {
+ if ((ano_modclose(handle)) != 0)
+ alog("%s", ano_moderr());
+ }
+}