diff options
-rw-r--r-- | include/extensible.h | 3 | ||||
-rw-r--r-- | src/base.cpp | 20 | ||||
-rw-r--r-- | src/modules.cpp | 8 | ||||
-rw-r--r-- | src/modules/m_cloaking.cpp | 7 |
4 files changed, 30 insertions, 8 deletions
diff --git a/include/extensible.h b/include/extensible.h index 3f5998231..d3d22a97e 100644 --- a/include/extensible.h +++ b/include/extensible.h @@ -81,7 +81,8 @@ class CoreExport Extensible : public classbase virtual ~Extensible(); static bool Register(ExtensionItem* item); - static void UnRegister(Module* module); + static std::vector<ExtensionItem*> BeginUnregister(Module* module); + void doUnhookExtensions(const std::vector<ExtensionItem*>& toRemove); // Friend access for the protected getter/setter friend class ExtensionItem; diff --git a/src/base.cpp b/src/base.cpp index aac66fd3f..27eb4af23 100644 --- a/src/base.cpp +++ b/src/base.cpp @@ -122,14 +122,32 @@ bool Extensible::Register(ExtensionItem* item) return Extensible::extension_types.insert(std::make_pair(item->key, item)).second; } -void Extensible::UnRegister(Module* module) +std::vector<ExtensionItem*> Extensible::BeginUnregister(Module* module) { + std::vector<ExtensionItem*> rv; ExtensibleTypes::iterator i = extension_types.begin(); while (i != extension_types.end()) { ExtensibleTypes::iterator c = i++; if (c->second->owner == module) + { + rv.push_back(c->second); extension_types.erase(c); + } + } + return rv; +} + +void Extensible::doUnhookExtensions(const std::vector<ExtensionItem*>& toRemove) +{ + for(std::vector<ExtensionItem*>::const_iterator i = toRemove.begin(); i != toRemove.end(); i++) + { + ExtensibleStore::iterator e = extensions.find((**i).key); + if (e != extensions.end()) + { + (**i).free(e->second); + extensions.erase(e); + } } } diff --git a/src/modules.cpp b/src/modules.cpp index 48b477658..51fecb47c 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -538,26 +538,30 @@ bool ModuleManager::Unload(const char* filename) return false; } + std::vector<ExtensionItem*> items = Extensible::BeginUnregister(modfind->second.second); /* Give the module a chance to tidy out all its metadata */ for (chan_hash::iterator c = ServerInstance->chanlist->begin(); c != ServerInstance->chanlist->end(); c++) { modfind->second.second->OnCleanup(TYPE_CHANNEL,c->second); + c->second->doUnhookExtensions(items); + const UserMembList* users = c->second->GetUsers(); + for(UserMembCIter mi = users->begin(); mi != users->end(); mi++) + mi->second->doUnhookExtensions(items); } for (user_hash::iterator u = ServerInstance->Users->clientlist->begin(); u != ServerInstance->Users->clientlist->end(); u++) { modfind->second.second->OnCleanup(TYPE_USER,u->second); + u->second->doUnhookExtensions(items); } /* Tidy up any dangling resolvers */ ServerInstance->Res->CleanResolvers(modfind->second.second); - FOREACH_MOD_I(ServerInstance,I_OnUnloadModule,OnUnloadModule(modfind->second.second, modfind->first)); this->DetachAll(modfind->second.second); ServerInstance->Parser->RemoveCommands(modfind->second.second); - Extensible::UnRegister(modfind->second.second); delete modfind->second.second; delete modfind->second.first; diff --git a/src/modules/m_cloaking.cpp b/src/modules/m_cloaking.cpp index 50bb4c4b6..fe802164d 100644 --- a/src/modules/m_cloaking.cpp +++ b/src/modules/m_cloaking.cpp @@ -63,7 +63,7 @@ class CloakUser : public ModeHandler return host.substr(splitdot); } - CloakUser(InspIRCd* Instance, Module* source, Module* Hash) + CloakUser(Module* source, Module* Hash) : ModeHandler(source, 'x', PARAM_NONE, MODETYPE_USER), HashProvider(Hash), ext("cloaked_host", source) { @@ -256,15 +256,14 @@ class ModuleCloaking : public Module CloakUser* cu; public: - ModuleCloaking(InspIRCd* Me) - : Module(Me) + ModuleCloaking(InspIRCd*) { /* Attempt to locate the md5 service provider, bail if we can't find it */ Module* HashModule = ServerInstance->Modules->Find("m_md5.so"); if (!HashModule) throw ModuleException("Can't find m_md5.so. Please load m_md5.so before m_cloaking.so."); - cu = new CloakUser(ServerInstance, this, HashModule); + cu = new CloakUser(this, HashModule); try { |