fixed bug amb659 (unloading parent extensions)

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401156
This commit is contained in:
David Anderson 2007-07-23 20:20:45 +00:00
parent 8b758a079a
commit 30b475ef35
2 changed files with 57 additions and 7 deletions

View File

@ -192,6 +192,32 @@ void CExtension::AddDependency(IfaceInfo *pInfo)
m_Deps.push_back(*pInfo); m_Deps.push_back(*pInfo);
} }
bool operator ==(const IfaceInfo &i1, const IfaceInfo &i2)
{
return (i1.iface == i2.iface) && (i1.owner == i2.owner);
}
void CExtension::AddChildDependent(CExtension *pOther, SMInterface *iface)
{
IfaceInfo info;
info.iface = iface;
info.owner = pOther;
List<IfaceInfo>::iterator iter;
for (iter = m_ChildDeps.begin();
iter != m_ChildDeps.end();
iter++)
{
IfaceInfo &other = (*iter);
if (other == info)
{
return;
}
}
m_ChildDeps.push_back(info);
}
ITERATOR *CExtension::FindFirstDependency(IExtension **pOwner, SMInterface **pInterface) ITERATOR *CExtension::FindFirstDependency(IExtension **pOwner, SMInterface **pInterface)
{ {
List<IfaceInfo>::iterator iter = m_Deps.begin(); List<IfaceInfo>::iterator iter = m_Deps.begin();
@ -463,11 +489,18 @@ IExtension *CExtensionManager::LoadExtension(const char *file, ExtensionLifetime
return pExt; return pExt;
} }
void CExtensionManager::BindDependency(IExtension *pOwner, IfaceInfo *pInfo) void CExtensionManager::BindDependency(IExtension *pRequester, IfaceInfo *pInfo)
{ {
CExtension *pExt = (CExtension *)pOwner; CExtension *pExt = (CExtension *)pRequester;
CExtension *pOwner = (CExtension *)pInfo->owner;
pExt->AddDependency(pInfo); pExt->AddDependency(pInfo);
IExtensionInterface *pAPI = pExt->GetAPI();
if (pAPI && !pAPI->QueryInterfaceDrop(pInfo->iface))
{
pOwner->AddChildDependent(pExt, pInfo->iface);
}
} }
void CExtensionManager::AddInterface(IExtension *pOwner, SMInterface *pInterface) void CExtensionManager::AddInterface(IExtension *pOwner, SMInterface *pInterface)
@ -628,9 +661,13 @@ bool CExtensionManager::UnloadExtension(IExtension *_pExt)
{ {
if ((*i_iter).owner == _pExt) if ((*i_iter).owner == _pExt)
{ {
if (!dropped && !pAPI->QueryInterfaceDrop((*i_iter).iface)) if (!pAPI->QueryInterfaceDrop((*i_iter).iface))
{
if (!dropped)
{ {
dropped = true; dropped = true;
UnloadQueue.push_back(pDep);
}
} }
pAPI->NotifyInterfaceDrop((*i_iter).iface); pAPI->NotifyInterfaceDrop((*i_iter).iface);
i_iter = pDep->m_Deps.erase(i_iter); i_iter = pDep->m_Deps.erase(i_iter);
@ -638,6 +675,17 @@ bool CExtensionManager::UnloadExtension(IExtension *_pExt)
i_iter++; i_iter++;
} }
} }
/* Flush out any back references to this plugin */
i_iter = pDep->m_ChildDeps.begin();
while (i_iter != pDep->m_ChildDeps.end())
{
if ((*i_iter).owner == pExt)
{
i_iter = pDep->m_ChildDeps.erase(i_iter);
} else {
i_iter++;
}
}
} }
} }
@ -841,7 +889,7 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmd, unsigned int argco
} }
if (!pExt->IsLoaded() if (!pExt->IsLoaded()
|| (!pExt->m_Deps.size() && !pExt->m_Plugins.size())) || (!pExt->m_ChildDeps.size() && !pExt->m_Plugins.size()))
{ {
char filename[PLATFORM_MAX_PATH]; char filename[PLATFORM_MAX_PATH];
snprintf(filename, PLATFORM_MAX_PATH, "%s", pExt->GetFilename()); snprintf(filename, PLATFORM_MAX_PATH, "%s", pExt->GetFilename());
@ -850,7 +898,7 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmd, unsigned int argco
return; return;
} else { } else {
List<IPlugin *> plugins; List<IPlugin *> plugins;
if (pExt->m_Deps.size()) if (pExt->m_ChildDeps.size())
{ {
g_RootMenu.ConsolePrint("[SM] Unloading %s will unload the following extensions: ", pExt->GetFilename()); g_RootMenu.ConsolePrint("[SM] Unloading %s will unload the following extensions: ", pExt->GetFilename());
List<CExtension *>::iterator iter; List<CExtension *>::iterator iter;

View File

@ -47,6 +47,7 @@ public: //IExtension
public: public:
void SetError(const char *error); void SetError(const char *error);
void AddDependency(IfaceInfo *pInfo); void AddDependency(IfaceInfo *pInfo);
void AddChildDependent(CExtension *pOther, SMInterface *iface);
void AddInterface(SMInterface *pInterface); void AddInterface(SMInterface *pInterface);
void AddPlugin(IPlugin *pPlugin); void AddPlugin(IPlugin *pPlugin);
void RemovePlugin(IPlugin *pPlugin); void RemovePlugin(IPlugin *pPlugin);
@ -60,7 +61,8 @@ private:
String m_Path; String m_Path;
ILibrary *m_pLib; ILibrary *m_pLib;
String m_Error; String m_Error;
List<IfaceInfo> m_Deps; List<IfaceInfo> m_Deps; /** Dependencies */
List<IfaceInfo> m_ChildDeps; /** Children who might depend on us */
List<SMInterface *> m_Interfaces; List<SMInterface *> m_Interfaces;
List<IPlugin *> m_Plugins; List<IPlugin *> m_Plugins;
List<const sp_nativeinfo_t *> m_Natives; List<const sp_nativeinfo_t *> m_Natives;