From 30b475ef35430550bc3d86d950b1041906af3eb0 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Mon, 23 Jul 2007 20:20:45 +0000 Subject: [PATCH] fixed bug amb659 (unloading parent extensions) --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401156 --- core/systems/ExtensionSys.cpp | 60 +++++++++++++++++++++++++++++++---- core/systems/ExtensionSys.h | 4 ++- 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/core/systems/ExtensionSys.cpp b/core/systems/ExtensionSys.cpp index f60043ed..0f45f27c 100644 --- a/core/systems/ExtensionSys.cpp +++ b/core/systems/ExtensionSys.cpp @@ -192,6 +192,32 @@ void CExtension::AddDependency(IfaceInfo *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::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) { List::iterator iter = m_Deps.begin(); @@ -463,11 +489,18 @@ IExtension *CExtensionManager::LoadExtension(const char *file, ExtensionLifetime 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); + + IExtensionInterface *pAPI = pExt->GetAPI(); + if (pAPI && !pAPI->QueryInterfaceDrop(pInfo->iface)) + { + pOwner->AddChildDependent(pExt, pInfo->iface); + } } void CExtensionManager::AddInterface(IExtension *pOwner, SMInterface *pInterface) @@ -628,9 +661,13 @@ bool CExtensionManager::UnloadExtension(IExtension *_pExt) { if ((*i_iter).owner == _pExt) { - if (!dropped && !pAPI->QueryInterfaceDrop((*i_iter).iface)) + if (!pAPI->QueryInterfaceDrop((*i_iter).iface)) { - dropped = true; + if (!dropped) + { + dropped = true; + UnloadQueue.push_back(pDep); + } } pAPI->NotifyInterfaceDrop((*i_iter).iface); i_iter = pDep->m_Deps.erase(i_iter); @@ -638,6 +675,17 @@ bool CExtensionManager::UnloadExtension(IExtension *_pExt) 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() - || (!pExt->m_Deps.size() && !pExt->m_Plugins.size())) + || (!pExt->m_ChildDeps.size() && !pExt->m_Plugins.size())) { char filename[PLATFORM_MAX_PATH]; snprintf(filename, PLATFORM_MAX_PATH, "%s", pExt->GetFilename()); @@ -850,7 +898,7 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmd, unsigned int argco return; } else { List plugins; - if (pExt->m_Deps.size()) + if (pExt->m_ChildDeps.size()) { g_RootMenu.ConsolePrint("[SM] Unloading %s will unload the following extensions: ", pExt->GetFilename()); List::iterator iter; diff --git a/core/systems/ExtensionSys.h b/core/systems/ExtensionSys.h index 26859faa..f35a8620 100644 --- a/core/systems/ExtensionSys.h +++ b/core/systems/ExtensionSys.h @@ -47,6 +47,7 @@ public: //IExtension public: void SetError(const char *error); void AddDependency(IfaceInfo *pInfo); + void AddChildDependent(CExtension *pOther, SMInterface *iface); void AddInterface(SMInterface *pInterface); void AddPlugin(IPlugin *pPlugin); void RemovePlugin(IPlugin *pPlugin); @@ -60,7 +61,8 @@ private: String m_Path; ILibrary *m_pLib; String m_Error; - List m_Deps; + List m_Deps; /** Dependencies */ + List m_ChildDeps; /** Children who might depend on us */ List m_Interfaces; List m_Plugins; List m_Natives;