fixed a dep bug
fixed a plugin unload iterator bug extension unloading now works --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40316
This commit is contained in:
parent
1efdacd69b
commit
4ac5297d11
@ -5,6 +5,7 @@
|
||||
#include "sourcemm_api.h"
|
||||
#include "PluginSys.h"
|
||||
#include "sm_srvcmds.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
CExtensionManager g_Extensions;
|
||||
IdentityType_t g_ExtType;
|
||||
@ -15,6 +16,7 @@ CExtension::CExtension(const char *filename, char *error, size_t err_max)
|
||||
m_pAPI = NULL;
|
||||
m_pIdentToken = NULL;
|
||||
m_PlId = 0;
|
||||
unload_code = 0;
|
||||
|
||||
char path[PLATFORM_MAX_PATH+1];
|
||||
g_LibSys.PathFormat(path, PLATFORM_MAX_PATH, "%s/extensions/%s", g_SourceMod.GetSMBaseDir(), filename);
|
||||
@ -349,6 +351,27 @@ void CExtensionManager::OnPluginDestroyed(IPlugin *plugin)
|
||||
}
|
||||
}
|
||||
|
||||
CExtension *CExtensionManager::FindByOrder(unsigned int num)
|
||||
{
|
||||
if (num < 1 || num > m_Libs.size())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
List<CExtension *>::iterator iter = m_Libs.begin();
|
||||
|
||||
while (iter != m_Libs.end())
|
||||
{
|
||||
if (--num == 0)
|
||||
{
|
||||
return (*iter);
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool CExtensionManager::UnloadExtension(IExtension *_pExt)
|
||||
{
|
||||
if (!_pExt)
|
||||
@ -376,9 +399,9 @@ bool CExtensionManager::UnloadExtension(IExtension *_pExt)
|
||||
List<IPlugin *>::iterator p_iter = pExt->m_Plugins.begin();
|
||||
while (p_iter != pExt->m_Plugins.end())
|
||||
{
|
||||
/* We have to manually unlink ourselves here, since we're no longer being managed */
|
||||
g_PluginSys.UnloadPlugin((*p_iter));
|
||||
/* It should already have been removed! */
|
||||
assert(pExt->m_Plugins.find((*p_iter)) != pExt->m_Plugins.end());
|
||||
p_iter = pExt->m_Plugins.erase(p_iter);
|
||||
}
|
||||
|
||||
/* Notify and/or unload all dependencies */
|
||||
@ -392,6 +415,10 @@ bool CExtensionManager::UnloadExtension(IExtension *_pExt)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (pDep == pExt)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
/* Now, get its dependency list */
|
||||
bool dropped = false;
|
||||
List<IfaceInfo>::iterator i_iter = pDep->m_Deps.begin();
|
||||
@ -524,10 +551,122 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmd, unsigned int argco
|
||||
g_RootMenu.ConsolePrint(" Metamod enabled: %s", pAPI->IsMetamodExtension() ? "yes" : "no");
|
||||
}
|
||||
return;
|
||||
} else if (strcmp(cmd, "unload") == 0) {
|
||||
if (argcount < 4)
|
||||
{
|
||||
g_RootMenu.ConsolePrint("[SM] Usage: sm unload <#> [code]");
|
||||
return;
|
||||
}
|
||||
|
||||
const char *arg = g_RootMenu.GetArgument(3);
|
||||
unsigned int num = atoi(arg);
|
||||
CExtension *pExt = FindByOrder(num);
|
||||
|
||||
if (!pExt)
|
||||
{
|
||||
g_RootMenu.ConsolePrint("[SM] Extension number %d was not found.", num);
|
||||
return;
|
||||
}
|
||||
|
||||
if (argcount > 4 && pExt->unload_code)
|
||||
{
|
||||
const char *unload = g_RootMenu.GetArgument(4);
|
||||
if (pExt->unload_code == atoi(unload))
|
||||
{
|
||||
char filename[PLATFORM_MAX_PATH+1];
|
||||
snprintf(filename, PLATFORM_MAX_PATH, "%s", pExt->GetFilename());
|
||||
UnloadExtension(pExt);
|
||||
g_RootMenu.ConsolePrint("[SM] Extension %s is now unloaded.", filename);
|
||||
} else {
|
||||
g_RootMenu.ConsolePrint("[SM] Please try again, the correct unload code is \"%d\"", pExt->unload_code);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pExt->IsLoaded()
|
||||
|| (!pExt->m_Deps.size() && !pExt->m_Plugins.size()))
|
||||
{
|
||||
char filename[PLATFORM_MAX_PATH+1];
|
||||
snprintf(filename, PLATFORM_MAX_PATH, "%s", pExt->GetFilename());
|
||||
UnloadExtension(pExt);
|
||||
g_RootMenu.ConsolePrint("[SM] Extension %s is now unloaded.", filename);
|
||||
return;
|
||||
} else {
|
||||
List<IPlugin *> plugins;
|
||||
if (pExt->m_Deps.size())
|
||||
{
|
||||
g_RootMenu.ConsolePrint("[SM] Unloading %s will unload the following extensions: ", pExt->GetFilename());
|
||||
List<CExtension *>::iterator iter;
|
||||
CExtension *pOther;
|
||||
/* Get list of all extensions */
|
||||
for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++)
|
||||
{
|
||||
List<IfaceInfo>::iterator i_iter;
|
||||
pOther = (*iter);
|
||||
if (!pOther->IsLoaded() || pOther == pExt)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
/* Get their dependencies */
|
||||
for (i_iter=pOther->m_Deps.begin();
|
||||
i_iter!=pOther->m_Deps.end();
|
||||
i_iter++)
|
||||
{
|
||||
/* Is this dependency to us? */
|
||||
if ((*i_iter).owner != pExt)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
/* Will our dependent care? */
|
||||
if (!pExt->GetAPI()->QueryInterfaceDrop((*i_iter).iface))
|
||||
{
|
||||
g_RootMenu.ConsolePrint(" -> %s", pExt->GetFilename());
|
||||
/* Add to plugin unload list */
|
||||
List<IPlugin *>::iterator p_iter;
|
||||
for (p_iter=pOther->m_Plugins.begin();
|
||||
p_iter!=pOther->m_Plugins.end();
|
||||
p_iter++)
|
||||
{
|
||||
if (plugins.find((*p_iter)) == plugins.end())
|
||||
{
|
||||
plugins.push_back((*p_iter));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pExt->m_Plugins.size())
|
||||
{
|
||||
g_RootMenu.ConsolePrint("[SM] Unloading %s will unload the following plugins: ", pExt->GetFilename());
|
||||
List<IPlugin *>::iterator iter;
|
||||
IPlugin *pPlugin;
|
||||
for (iter = pExt->m_Plugins.begin(); iter != pExt->m_Plugins.end(); iter++)
|
||||
{
|
||||
pPlugin = (*iter);
|
||||
if (plugins.find(pPlugin) == plugins.end())
|
||||
{
|
||||
plugins.push_back(pPlugin);
|
||||
}
|
||||
}
|
||||
for (iter = plugins.begin(); iter != plugins.end(); iter++)
|
||||
{
|
||||
pPlugin = (*iter);
|
||||
g_RootMenu.ConsolePrint(" -> %s", pPlugin->GetFilename());
|
||||
}
|
||||
}
|
||||
srand(static_cast<int>(time(NULL)));
|
||||
pExt->unload_code = (rand() % 877) + 123; //123 to 999
|
||||
g_RootMenu.ConsolePrint("[SM] To verify unloading %s, please use the following: ", pExt->GetFilename());
|
||||
g_RootMenu.ConsolePrint("[SM] sm exts unload %d %d", num, pExt->unload_code);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_RootMenu.ConsolePrint("SourceMod Extensions Menu:");
|
||||
g_RootMenu.DrawGenericOption("info", "Extra extension information");
|
||||
g_RootMenu.DrawGenericOption("list", "List extensions");
|
||||
g_RootMenu.DrawGenericOption("unload", "Unload an extension");
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ private:
|
||||
List<SMInterface *> m_Interfaces;
|
||||
List<IPlugin *> m_Plugins;
|
||||
PluginId m_PlId;
|
||||
unsigned int unload_code;
|
||||
};
|
||||
|
||||
class CExtensionManager :
|
||||
@ -72,6 +73,8 @@ public:
|
||||
void BindDependency(IExtension *pOwner, IfaceInfo *pInfo);
|
||||
void AddInterface(IExtension *pOwner, SMInterface *pInterface);
|
||||
void BindChildPlugin(IExtension *pParent, IPlugin *pPlugin);
|
||||
private:
|
||||
CExtension *FindByOrder(unsigned int num);
|
||||
private:
|
||||
List<CExtension *> m_Libs;
|
||||
};
|
||||
|
@ -966,7 +966,7 @@ bool CPluginManager::UnloadPlugin(IPlugin *plugin)
|
||||
List<IPluginsListener *>::iterator iter;
|
||||
IPluginsListener *pListener;
|
||||
|
||||
if (pPlugin->GetStatus() >= Plugin_Error)
|
||||
if (pPlugin->GetStatus() <= Plugin_Error)
|
||||
{
|
||||
/* Notify listeners of unloading */
|
||||
for (iter=m_listeners.begin(); iter!=m_listeners.end(); iter++)
|
||||
|
@ -113,7 +113,7 @@ bool ShareSystem::AddInterface(IExtension *myself, SMInterface *iface)
|
||||
|
||||
bool ShareSystem::RequestInterface(const char *iface_name,
|
||||
unsigned int iface_vers,
|
||||
IExtension *mysql,
|
||||
IExtension *myself,
|
||||
SMInterface **pIface)
|
||||
{
|
||||
/* See if the interface exists */
|
||||
@ -148,7 +148,7 @@ bool ShareSystem::RequestInterface(const char *iface_name,
|
||||
IfaceInfo info;
|
||||
info.iface = iface;
|
||||
info.owner = iface_owner;
|
||||
g_Extensions.BindDependency(iface_owner, &info);
|
||||
g_Extensions.BindDependency(myself, &info);
|
||||
}
|
||||
|
||||
if (pIface)
|
||||
|
Loading…
Reference in New Issue
Block a user