diff --git a/include/modules.h b/include/modules.h index 644674157..7eaabc91b 100644 --- a/include/modules.h +++ b/include/modules.h @@ -996,22 +996,22 @@ extern ModData *moddata_client_get_raw(Client *client, const char *varname); extern int moddata_local_client_set(Client *acptr, const char *varname, const char *value); extern const char *moddata_local_client_get(Client *acptr, const char *varname); -extern int LoadPersistentPointerX(ModuleInfo *modinfo, const char *varshortname, void **var, void (*free_variable)(ModData *m)); +extern void LoadPersistentPointerX(ModuleInfo *modinfo, const char *varshortname, void **var, void (*free_variable)(ModData *m)); #define LoadPersistentPointer(modinfo, var, free_variable) LoadPersistentPointerX(modinfo, #var, (void **)&var, free_variable) extern void SavePersistentPointerX(ModuleInfo *modinfo, const char *varshortname, void *var); #define SavePersistentPointer(modinfo, var) SavePersistentPointerX(modinfo, #var, var) -extern int LoadPersistentIntX(ModuleInfo *modinfo, const char *varshortname, int *var); +extern void LoadPersistentIntX(ModuleInfo *modinfo, const char *varshortname, int *var); #define LoadPersistentInt(modinfo, var) LoadPersistentIntX(modinfo, #var, &var) extern void SavePersistentIntX(ModuleInfo *modinfo, const char *varshortname, int var); #define SavePersistentInt(modinfo, var) SavePersistentIntX(modinfo, #var, var) -extern int LoadPersistentLongX(ModuleInfo *modinfo, const char *varshortname, long *var); +extern void LoadPersistentLongX(ModuleInfo *modinfo, const char *varshortname, long *var); #define LoadPersistentLong(modinfo, var) LoadPersistentLongX(modinfo, #var, &var) extern void SavePersistentLongX(ModuleInfo *modinfo, const char *varshortname, long var); #define SavePersistentLong(modinfo, var) SavePersistentLongX(modinfo, #var, var) -extern int LoadPersistentLongLongX(ModuleInfo *modinfo, const char *varshortname, long long *var); +extern void LoadPersistentLongLongX(ModuleInfo *modinfo, const char *varshortname, long long *var); #define LoadPersistentLongLong(modinfo, var) LoadPersistentLongLongX(modinfo, #var, &var) extern void SavePersistentLongLongX(ModuleInfo *modinfo, const char *varshortname, long long var); #define SavePersistentLongLong(modinfo, var) SavePersistentLongLongX(modinfo, #var, var) diff --git a/src/api-moddata.c b/src/api-moddata.c index aa0767142..31c84c892 100644 --- a/src/api-moddata.c +++ b/src/api-moddata.c @@ -285,24 +285,41 @@ void ModDataDel(ModDataInfo *md) break; } } + /* Module is unloading, so owner will be gone: */ md->owner = NULL; } if (loop.rehashing) + { + /* Since the module is unloaded, these are not safe anymore either: */ + md->free = NULL; + md->serialize = NULL; + md->unserialize = NULL; md->unloaded = 1; - else + } else { + /* We need the free function and the like, + * and then completely destroy 'md'. + */ unload_moddata_commit(md); + } } void unload_all_unused_moddata(void) { -ModDataInfo *md, *md_next; + ModDataInfo *md, *md_next; for (md = MDInfo; md; md = md_next) { md_next = md->next; if (md->unloaded) + { + //config_status("UNLOADING: md %s (owner %p, type %d, slot %d)", + // md->name, md->owner, md->type, md->slot); unload_moddata_commit(md); + } else { + //config_status("loaded: md %s (owner %p, type %d, slot %d)", + // md->name, md->owner, md->type, md->slot); + } } } diff --git a/src/conf.c b/src/conf.c index 1ecec29fe..1c7cb4db3 100644 --- a/src/conf.c +++ b/src/conf.c @@ -11152,7 +11152,7 @@ int rehash_internal(Client *client) unload_all_unused_caps(); unload_all_unused_history_backends(); unload_all_unused_rpc_handlers(); - // unload_all_unused_moddata(); -- this will crash + unload_all_unused_moddata(); clicap_check_for_changes(); umodes_check_for_changes(); charsys_check_for_changes(); diff --git a/src/modules.c b/src/modules.c index 6b6ae2d71..20e6f4874 100644 --- a/src/modules.c +++ b/src/modules.c @@ -1191,7 +1191,7 @@ EVENT(e_unload_module_delayed) if (i == 1) { unreal_log(ULOG_INFO, "module", "MODULE_UNLOADING_DELAYED", NULL, - "Unloading module $module_name (was delayed earlier)", + "Unloaded module $module_name (was delayed earlier)", log_data_string("module_name", name)); } safe_free(name); @@ -1364,16 +1364,24 @@ static const char *mod_var_name(ModuleInfo *modinfo, const char *varshortname) return fullname; } -int LoadPersistentPointerX(ModuleInfo *modinfo, const char *varshortname, void **var, void (*free_variable)(ModData *m)) +ModDataInfo *persistent_var_generic(ModuleInfo *modinfo, const char *varshortname, void (*free_variable)(ModData *m)) { ModDataInfo *m; const char *fullname = mod_var_name(modinfo, varshortname); + if (!modinfo) + abort(); + m = findmoddata_byname(fullname, MODDATATYPE_LOCAL_VARIABLE); if (m) { - *var = moddata_local_variable(m).ptr; - return 1; + if (loop.config_status != CONFIG_STATUS_TEST) + { + /* Claim ownership */ + m->owner = modinfo->handle; + m->unloaded = 0; + } + return m; } else { ModDataInfo mreq; memset(&mreq, 0, sizeof(mreq)); @@ -1381,114 +1389,57 @@ int LoadPersistentPointerX(ModuleInfo *modinfo, const char *varshortname, void * mreq.name = strdup(fullname); mreq.free = free_variable; m = ModDataAdd(modinfo->handle, mreq); - moddata_local_variable(m).ptr = NULL; safe_free(mreq.name); - return 0; + memset(&moddata_local_variable(m), 0, sizeof(ModData)); + return m; } } +void LoadPersistentPointerX(ModuleInfo *modinfo, const char *varshortname, void **var, void (*free_variable)(ModData *m)) +{ + ModDataInfo *m = persistent_var_generic(modinfo, varshortname, free_variable); + *var = moddata_local_variable(m).ptr; +} + +void LoadPersistentIntX(ModuleInfo *modinfo, const char *varshortname, int *var) +{ + ModDataInfo *m = persistent_var_generic(modinfo, varshortname, NULL); + *var = moddata_local_variable(m).i; +} + +void LoadPersistentLongX(ModuleInfo *modinfo, const char *varshortname, long *var) +{ + ModDataInfo *m = persistent_var_generic(modinfo, varshortname, NULL); + *var = moddata_local_variable(m).l; +} + +void LoadPersistentLongLongX(ModuleInfo *modinfo, const char *varshortname, long long *var) +{ + ModDataInfo *m = persistent_var_generic(modinfo, varshortname, NULL); + *var = moddata_local_variable(m).ll; +} + void SavePersistentPointerX(ModuleInfo *modinfo, const char *varshortname, void *var) { - ModDataInfo *m; - const char *fullname = mod_var_name(modinfo, varshortname); - - m = findmoddata_byname(fullname, MODDATATYPE_LOCAL_VARIABLE); + ModDataInfo *m = persistent_var_generic(modinfo, varshortname, NULL); moddata_local_variable(m).ptr = var; } -int LoadPersistentIntX(ModuleInfo *modinfo, const char *varshortname, int *var) -{ - ModDataInfo *m; - const char *fullname = mod_var_name(modinfo, varshortname); - - m = findmoddata_byname(fullname, MODDATATYPE_LOCAL_VARIABLE); - if (m) - { - *var = moddata_local_variable(m).i; - return 1; - } else { - ModDataInfo mreq; - memset(&mreq, 0, sizeof(mreq)); - mreq.type = MODDATATYPE_LOCAL_VARIABLE; - mreq.name = strdup(fullname); - mreq.free = NULL; - m = ModDataAdd(modinfo->handle, mreq); - moddata_local_variable(m).i = 0; - safe_free(mreq.name); - return 0; - } -} - void SavePersistentIntX(ModuleInfo *modinfo, const char *varshortname, int var) { - ModDataInfo *m; - const char *fullname = mod_var_name(modinfo, varshortname); - - m = findmoddata_byname(fullname, MODDATATYPE_LOCAL_VARIABLE); + ModDataInfo *m = persistent_var_generic(modinfo, varshortname, NULL); moddata_local_variable(m).i = var; } -int LoadPersistentLongX(ModuleInfo *modinfo, const char *varshortname, long *var) -{ - ModDataInfo *m; - const char *fullname = mod_var_name(modinfo, varshortname); - - m = findmoddata_byname(fullname, MODDATATYPE_LOCAL_VARIABLE); - if (m) - { - *var = moddata_local_variable(m).l; - return 1; - } else { - ModDataInfo mreq; - memset(&mreq, 0, sizeof(mreq)); - mreq.type = MODDATATYPE_LOCAL_VARIABLE; - mreq.name = strdup(fullname); - mreq.free = NULL; - m = ModDataAdd(modinfo->handle, mreq); - moddata_local_variable(m).l = 0; - safe_free(mreq.name); - return 0; - } -} - void SavePersistentLongX(ModuleInfo *modinfo, const char *varshortname, long var) { - ModDataInfo *m; - const char *fullname = mod_var_name(modinfo, varshortname); - - m = findmoddata_byname(fullname, MODDATATYPE_LOCAL_VARIABLE); + ModDataInfo *m = persistent_var_generic(modinfo, varshortname, NULL); moddata_local_variable(m).l = var; } -int LoadPersistentLongLongX(ModuleInfo *modinfo, const char *varshortname, long long *var) -{ - ModDataInfo *m; - const char *fullname = mod_var_name(modinfo, varshortname); - - m = findmoddata_byname(fullname, MODDATATYPE_LOCAL_VARIABLE); - if (m) - { - *var = moddata_local_variable(m).ll; - return 1; - } else { - ModDataInfo mreq; - memset(&mreq, 0, sizeof(mreq)); - mreq.type = MODDATATYPE_LOCAL_VARIABLE; - mreq.name = strdup(fullname); - mreq.free = NULL; - m = ModDataAdd(modinfo->handle, mreq); - moddata_local_variable(m).ll = 0; - safe_free(mreq.name); - return 0; - } -} - void SavePersistentLongLongX(ModuleInfo *modinfo, const char *varshortname, long long var) { - ModDataInfo *m; - const char *fullname = mod_var_name(modinfo, varshortname); - - m = findmoddata_byname(fullname, MODDATATYPE_LOCAL_VARIABLE); + ModDataInfo *m = persistent_var_generic(modinfo, varshortname, NULL); moddata_local_variable(m).ll = var; }