X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules.cpp;h=8af5b95e33e1153d9b298ae212de4f19fc78b1d6;hb=e245dbbad7e91f232482374e9166f18782eaafa0;hp=9e5c84bfff3d8e32412b9db1773c21bcc27ac2f3;hpb=11e45f2cb78c0667e2c7c7e2370944bf64b140b8;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules.cpp b/src/modules.cpp index 9e5c84bff..8af5b95e3 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -23,24 +23,24 @@ #include #endif +static std::vector* dynrefs = NULL; -// Version is a simple class for holding a modules version number -template<> -VersionBase::VersionBase(const std::string &desc, int flags) -: description(desc), Flags(flags) +void dynamic_reference_base::reset_all() { + if (!dynrefs) + return; + for(unsigned int i = 0; i < dynrefs->size(); i++) + (*dynrefs)[i]->ClearCache(); } -template<> -VersionBase::VersionBase(const std::string &desc, int flags, const std::string& linkdata) -: description(desc), Flags(flags), link_data(linkdata) +// Version is a simple class for holding a modules version number +Version::Version(const std::string &desc, int flags) : description(desc), Flags(flags) { } -template<> -bool VersionBase::CanLink(const std::string& other_data) +Version::Version(const std::string &desc, int flags, const std::string& linkdata) +: description(desc), Flags(flags), link_data(linkdata) { - return link_data == other_data; } Request::Request(Module* src, Module* dst, const char* idstr) @@ -162,7 +162,7 @@ void Module::OnNamesListItem(User*, Membership*, std::string&, std::string&) { ModResult Module::OnNumeric(User*, unsigned int, const std::string&) { return MOD_RES_PASSTHRU; } void Module::OnHookIO(StreamSocket*, ListenSocket*) { } ModResult Module::OnAcceptConnection(int, ListenSocket*, irc::sockets::sockaddrs*, irc::sockets::sockaddrs*) { return MOD_RES_PASSTHRU; } -void Module::OnSendWhoLine(User*, const std::vector&, User*, Channel*, std::string&) { } +void Module::OnSendWhoLine(User*, const std::vector&, User*, std::string&) { } ModuleManager::ModuleManager() : ModCount(0) { @@ -368,8 +368,8 @@ void ModuleManager::DoSafeUnload(Module* mod) if (curr->second->creator == mod) DataProviders.erase(curr); } - for(unsigned int i = 0; i < ServerInstance->Modules->ActiveDynrefs.size(); i++) - ServerInstance->Modules->ActiveDynrefs[i]->ClearCache(); + + dynamic_reference_base::reset_all(); /* Tidy up any dangling resolvers */ ServerInstance->Res->CleanResolvers(mod); @@ -386,6 +386,29 @@ void ModuleManager::DoSafeUnload(Module* mod) ServerInstance->BuildISupport(); } +void ModuleManager::UnloadAll() +{ + /* We do this more than once, so that any service providers get a + * chance to be unhooked by the modules using them, but then get + * a chance to be removed themsleves. + * + * Note: this deliberately does NOT delete the DLLManager objects + */ + for (int tries = 0; tries < 4; tries++) + { + std::map::iterator i = Modules.begin(); + while (i != Modules.end()) + { + std::map::iterator me = i++; + if (CanUnload(me->second)) + { + DoSafeUnload(me->second); + } + } + ServerInstance->GlobalCulls.Apply(); + } +} + std::string& ModuleManager::LastError() { return LastModuleError; @@ -454,8 +477,7 @@ void ModuleManager::DelService(ServiceProvider& item) if (curr->second == &item) DataProviders.erase(curr); } - for(unsigned int i = 0; i < ServerInstance->Modules->ActiveDynrefs.size(); i++) - ServerInstance->Modules->ActiveDynrefs[i]->ClearCache(); + dynamic_reference_base::reset_all(); return; } default: @@ -484,19 +506,26 @@ ServiceProvider* ModuleManager::FindService(ServiceType type, const std::string& dynamic_reference_base::dynamic_reference_base(Module* Creator, const std::string& Name) : name(Name), value(NULL), creator(Creator) { - ServerInstance->Modules->ActiveDynrefs.push_back(this); + if (!dynrefs) + dynrefs = new std::vector; + dynrefs->push_back(this); } dynamic_reference_base::~dynamic_reference_base() { - for(unsigned int i = 0; i < ServerInstance->Modules->ActiveDynrefs.size(); i++) + for(unsigned int i = 0; i < dynrefs->size(); i++) { - if (ServerInstance->Modules->ActiveDynrefs[i] == this) + if (dynrefs->at(i) == this) { - unsigned int last = ServerInstance->Modules->ActiveDynrefs.size() - 1; + unsigned int last = dynrefs->size() - 1; if (i != last) - ServerInstance->Modules->ActiveDynrefs[i] = ServerInstance->Modules->ActiveDynrefs[last]; - ServerInstance->Modules->ActiveDynrefs.erase(ServerInstance->Modules->ActiveDynrefs.begin() + last); + dynrefs->at(i) = dynrefs->at(last); + dynrefs->erase(dynrefs->begin() + last); + if (dynrefs->empty()) + { + delete dynrefs; + dynrefs = NULL; + } return; } }