summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>2009-09-15 21:25:30 +0000
committerdanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>2009-09-15 21:25:30 +0000
commit01c23b31f7d0ea87052cd22814af826ecb11f0f3 (patch)
tree53743a6950d0ddafe6c8319eecf09b1c6d1687a2
parent94d7827e8b101b528c427298fada73664970cf26 (diff)
Remove Extensible items from user, channel, and Membership on module unload
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11730 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r--include/extensible.h3
-rw-r--r--src/base.cpp20
-rw-r--r--src/modules.cpp8
-rw-r--r--src/modules/m_cloaking.cpp7
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
{