]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules.cpp
Remove our vectors of Module*/ircd_module*, replace with a map of std::pair<ircd_modu...
[user/henk/code/inspircd.git] / src / modules.cpp
index 3a916e8a63b52177e5da31dbbb2510790626acea..7bc9f94c4ffee801216513fdd3e16544dc8717cc 100644 (file)
@@ -235,10 +235,19 @@ bool ModuleManager::SetPriority(Module* mod, PriorityState s)
 {
        for (size_t n = I_BEGIN + 1; n != I_END; ++n)
                SetPriority(mod, (Implementation)n, s);
+
+       return true;
 }
 
 bool ModuleManager::SetPriority(Module* mod, Implementation i, PriorityState s, Module** modules, size_t sz)
 {
+       if (GetModuleName(mod) != "m_spanningtree.so")
+               Instance->Log(DEBUG,"ModuleManager::SetPriority called by %s, priority state %s num_modules=%u", GetModuleName(mod).c_str(), s == PRIO_BEFORE ? "PRIO_BEFORE" : 
+                       s == PRIO_AFTER ? "PRIO_AFTER" :
+                       s == PRIO_LAST ? "PRIO_LAST" :
+                       s == PRIO_FIRST ? "PRIO_FIRST" : "<unknown!>",
+                       sz);
+
        size_t swap_pos;
        size_t source = 0;
        bool swap = true;
@@ -257,6 +266,19 @@ bool ModuleManager::SetPriority(Module* mod, Implementation i, PriorityState s,
        if (!found)
                return false;
 
+       Instance->Log(DEBUG,"ModuleManager::SetPriority: My position: %u", source);
+
+       if (modules)
+       {
+               for (size_t n = 0; n < sz; ++n)
+               {
+                       if (modules[n])
+                               Instance->Log(DEBUG,"    Listed Module: [%08x] %s", modules[n], GetModuleName(modules[n]).c_str());
+                       else
+                               Instance->Log(DEBUG,"    [null module]");
+               }
+       }
+
        switch (s)
        {
                case PRIO_DONTCARE:
@@ -275,12 +297,16 @@ bool ModuleManager::SetPriority(Module* mod, Implementation i, PriorityState s,
                {
                        /* Find the latest possible position */
                        swap_pos = 0;
+                       swap = false;
                        for (size_t x = 0; x != EventHandlers[i].size(); ++x)
                        {
                                for (size_t n = 0; n < sz; ++n)
                                {
-                                       if ((modules[n]) && (EventHandlers[i][x] == modules[n]) && (x >= swap_pos))
+                                       if ((modules[n]) && (EventHandlers[i][x] == modules[n]) && (x >= swap_pos) && (source <= swap_pos))
+                                       {
                                                swap_pos = x;
+                                               swap = true;
+                                       }
                                }
                        }
                }
@@ -288,20 +314,35 @@ bool ModuleManager::SetPriority(Module* mod, Implementation i, PriorityState s,
                case PRIO_BEFORE:
                {
                        swap_pos = EventHandlers[i].size() - 1;
+                       swap = false;
                        for (size_t x = 0; x != EventHandlers[i].size(); ++x)
                        {
                                for (size_t n = 0; n < sz; ++n)
                                {
-                                       if ((modules[n]) && (EventHandlers[i][x] == modules[n]) && (x <= swap_pos))
+                                       if ((modules[n]) && (EventHandlers[i][x] == modules[n]) && (x <= swap_pos) && (source >= swap_pos))
+                                       {
+                                               swap = true;
                                                swap_pos = x;
+                                       }
                                }
                        }
                }
                break;
        }
 
-       if (swap)
+       if (swap && (swap_pos != source))
+       {
                std::swap(EventHandlers[i][swap_pos], EventHandlers[i][source]);
+               Instance->Log(DEBUG,"Swap locations %u and %u", swap_pos, source);
+       }
+       else
+               Instance->Log(DEBUG,"No need to swap");
+
+       Instance->Log(DEBUG,"New ordering:");
+       for (size_t x = 0; x != EventHandlers[i].size(); ++x)
+       {
+               Instance->Log(DEBUG,"  [%08x] %s", EventHandlers[i][x], GetModuleName(EventHandlers[i][x]).c_str());
+       }
 
        return true;
 }
@@ -360,7 +401,7 @@ bool ModuleManager::Load(const char* filename)
                return false;
        }
        
-       if(find(Instance->Config->module_names.begin(), Instance->Config->module_names.end(), filename_str) != Instance->Config->module_names.end())
+       if (Modules.find(filename_str) != Modules.end())
        {       
                Instance->Log(DEFAULT,"Module %s is already loaded, cannot load a module twice!",modfile);
                snprintf(MODERR, MAXBUF, "Module already loaded");
@@ -379,10 +420,7 @@ bool ModuleManager::Load(const char* filename)
                 * the module file or getting a pointer to the init_module symbol.
                 */
                newhandle = new ircd_module(Instance, modfile, "init_module");
-                       
-               handles[this->ModCount+1] = newhandle;
-                       
-               newmod = handles[this->ModCount+1]->CallInit();
+               newmod = newhandle->CallInit();
 
                if(newmod)
                {
@@ -400,11 +438,7 @@ bool ModuleManager::Load(const char* filename)
                                Instance->Log(DEFAULT,"New module introduced: %s (API version %d, Module version %d.%d.%d.%d)%s", filename, v.API, v.Major, v.Minor, v.Revision, v.Build, (!(v.Flags & VF_VENDOR) ? " [3rd Party]" : " [Vendor]"));
                        }
 
-                       modules[this->ModCount+1] = newmod;
-                               
-                       /* save the module and the module's classfactory, if
-                        * this isnt done, random crashes can occur :/ */
-                       Instance->Config->module_names.push_back(filename);
+                       Modules[filename_str] = std::make_pair(newhandle, newmod);
                }
                else
                {
@@ -433,123 +467,70 @@ bool ModuleManager::Load(const char* filename)
        }
        
        this->ModCount++;
-       FOREACH_MOD_I(Instance,I_OnLoadModule,OnLoadModule(modules[this->ModCount],filename_str));
+       FOREACH_MOD_I(Instance,I_OnLoadModule,OnLoadModule(newmod, filename_str));
 
-       for (int n = 0; n != this->ModCount+1; ++n)
-               modules[n]->Prioritize();
+       for (std::map<std::string, std::pair<ircd_module*, Module*> >::iterator n = Modules.begin(); n != Modules.end(); ++n)
+               n->second.second->Prioritize();
 
        Instance->BuildISupport();
        return true;
 }
 
-bool ModuleManager::EraseHandle(unsigned int j)
-{
-       ModuleHandleList::iterator iter;
-       
-       if (j >= handles.size())
-       {
-               return false;
-       }
-       
-       iter = handles.begin() + j;
-
-       if(*iter)
-       {
-               delete *iter;   
-               handles.erase(iter);
-               handles.push_back(NULL);
-       }
-
-       return true;
-}
-
-bool ModuleManager::EraseModule(unsigned int j)
+bool ModuleManager::Unload(const char* filename)
 {
-       bool success = false;
-       
-       ModuleList::iterator iter;      
-       
-       if (j >= modules.size())
-       {
-               return false;
-       }
-
-       iter = modules.begin() + j;
-
-       if (*iter)
-       {
-               delete *iter;   
-               modules.erase(iter);
-               modules.push_back(NULL);
-               success = true;
-       }
+       std::string filename_str = filename;
+       std::map<std::string, std::pair<ircd_module*, Module*> >::iterator modfind = Modules.find(filename);
 
-       std::vector<std::string>::iterator iter2;
-       
-       if (j >= Instance->Config->module_names.size())
+       if (modfind != Modules.end())
        {
-               return false;
-       }
+               if (modfind->second.second->GetVersion().Flags & VF_STATIC)
+               {
+                       Instance->Log(DEFAULT,"Failed to unload STATIC module %s",filename);
+                       snprintf(MODERR,MAXBUF,"Module not unloadable (marked static)");
+                       return false;
+               }
+               std::pair<int,std::string> intercount = GetInterfaceInstanceCount(modfind->second.second);
+               if (intercount.first > 0)
+               {
+                       Instance->Log(DEFAULT,"Failed to unload module %s, being used by %d other(s) via interface '%s'",filename, intercount.first, intercount.second.c_str());
+                       snprintf(MODERR,MAXBUF,"Module not unloadable (Still in use by %d other module%s which %s using its interface '%s') -- unload dependent modules first!",
+                                       intercount.first,
+                                       intercount.first > 1 ? "s" : "",
+                                       intercount.first > 1 ? "are" : "is",
+                                       intercount.second.c_str());
+                       return false;
+               }
 
-       iter2 = Instance->Config->module_names.begin() + j;
+               /* Give the module a chance to tidy out all its metadata */
+               for (chan_hash::iterator c = Instance->chanlist->begin(); c != Instance->chanlist->end(); c++)
+               {
+                       modfind->second.second->OnCleanup(TYPE_CHANNEL,c->second);
+               }
+               for (user_hash::iterator u = Instance->clientlist->begin(); u != Instance->clientlist->end(); u++)
+               {
+                       modfind->second.second->OnCleanup(TYPE_USER,u->second);
+               }
 
-       Instance->Config->module_names.erase(iter2);
-       success = true;
+               /* Tidy up any dangling resolvers */
+               Instance->Res->CleanResolvers(modfind->second.second);
 
-       return success;
-}
 
-bool ModuleManager::Unload(const char* filename)
-{
-       std::string filename_str = filename;
-       for (unsigned int j = 0; j != Instance->Config->module_names.size(); j++)
-       {
-               if (Instance->Config->module_names[j] == filename_str)
-               {
-                       if (modules[j]->GetVersion().Flags & VF_STATIC)
-                       {
-                               Instance->Log(DEFAULT,"Failed to unload STATIC module %s",filename);
-                               snprintf(MODERR,MAXBUF,"Module not unloadable (marked static)");
-                               return false;
-                       }
-                       std::pair<int,std::string> intercount = GetInterfaceInstanceCount(modules[j]);
-                       if (intercount.first > 0)
-                       {
-                               Instance->Log(DEFAULT,"Failed to unload module %s, being used by %d other(s) via interface '%s'",filename, intercount.first, intercount.second.c_str());
-                               snprintf(MODERR,MAXBUF,"Module not unloadable (Still in use by %d other module%s which %s using its interface '%s') -- unload dependent modules first!",
-                                               intercount.first,
-                                               intercount.first > 1 ? "s" : "",
-                                               intercount.first > 1 ? "are" : "is",
-                                               intercount.second.c_str());
-                               return false;
-                       }
-                       /* Give the module a chance to tidy out all its metadata */
-                       for (chan_hash::iterator c = Instance->chanlist->begin(); c != Instance->chanlist->end(); c++)
-                       {
-                               modules[j]->OnCleanup(TYPE_CHANNEL,c->second);
-                       }
-                       for (user_hash::iterator u = Instance->clientlist->begin(); u != Instance->clientlist->end(); u++)
-                       {
-                               modules[j]->OnCleanup(TYPE_USER,u->second);
-                       }
+               FOREACH_MOD_I(Instance,I_OnUnloadModule,OnUnloadModule(modfind->second.second, modfind->first));
 
-                       /* Tidy up any dangling resolvers */
-                       Instance->Res->CleanResolvers(modules[j]);
+               this->DetachAll(modfind->second.second);
 
-                       FOREACH_MOD_I(Instance,I_OnUnloadModule,OnUnloadModule(modules[j],Instance->Config->module_names[j]));
+               Instance->Parser->RemoveCommands(filename);
 
-                       this->DetachAll(modules[j]);
+               delete modfind->second.second;
+               delete modfind->second.first;
+               Modules.erase(modfind);
 
-                       // found the module
-                       Instance->Parser->RemoveCommands(filename);
-                       this->EraseModule(j);
-                       this->EraseHandle(j);
-                       Instance->Log(DEFAULT,"Module %s unloaded",filename);
-                       this->ModCount--;
-                       Instance->BuildISupport();
-                       return true;
-               }
+               Instance->Log(DEFAULT,"Module %s unloaded",filename);
+               this->ModCount--;
+               Instance->BuildISupport();
+               return true;
        }
+
        Instance->Log(DEFAULT,"Module %s is not loaded, cannot unload it!",filename);
        snprintf(MODERR,MAXBUF,"Module not loaded");
        return false;
@@ -559,7 +540,6 @@ bool ModuleManager::Unload(const char* filename)
 void ModuleManager::LoadAll()
 {
        char configToken[MAXBUF];
-       Instance->Config->module_names.clear();
        ModCount = -1;
 
        for(int count = 0; count < Instance->Config->ConfValueEnum(Instance->Config->config_data, "module"); count++)
@@ -689,19 +669,15 @@ std::pair<int,std::string> ModuleManager::GetInterfaceInstanceCount(Module* m)
 
 const std::string& ModuleManager::GetModuleName(Module* m)
 {
-       static std::string nothing; /* Prevent compiler warning */
-
-       if (!this->GetCount())
-               return nothing;
+       static std::string nothing;
 
-       for (int i = 0; i <= this->GetCount(); i++)
+       for (std::map<std::string, std::pair<ircd_module*, Module*> >::iterator n = Modules.begin(); n != Modules.end(); ++n)
        {
-               if (this->modules[i] == m)
-               {
-                       return Instance->Config->module_names[i];
-               }
+               if (n->second.second == m)
+                       return n->first;
        }
-       return nothing; /* As above */
+
+       return nothing;
 }
 
 /* This is ugly, yes, but hash_map's arent designed to be
@@ -801,14 +777,12 @@ bool InspIRCd::AddResolver(Resolver* r, bool cached)
 
 Module* ModuleManager::Find(const std::string &name)
 {
-       for (int i = 0; i <= this->GetCount(); i++)
-       {
-               if (Instance->Config->module_names[i] == name)
-               {
-                       return this->modules[i];
-               }
-       }
-       return NULL;
+       std::map<std::string, std::pair<ircd_module*, Module*> >::iterator modfind = Modules.find(name);
+
+       if (modfind == Modules.end())
+               return NULL;
+       else
+               return modfind->second.second;
 }
 
 ConfigReader::ConfigReader(InspIRCd* Instance) : ServerInstance(Instance)