From c3cd2ac4a3dbfd4a42cefa2ca71df513443a0521 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Tue, 24 Jul 2007 02:24:37 +0000 Subject: [PATCH] added amb670 (exposed IDBThreadOperation to extensions) --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401163 --- core/Database.cpp | 49 ++++++++++++++++++++++++++++++++++- core/Database.h | 11 +------- core/sm_globals.h | 8 ++++++ core/sm_simple_prioqueue.h | 8 +----- core/smn_database.cpp | 19 +++++++++----- core/systems/ExtensionSys.cpp | 11 ++++++++ 6 files changed, 81 insertions(+), 25 deletions(-) diff --git a/core/Database.cpp b/core/Database.cpp index ab80aff2..d982d900 100644 --- a/core/Database.cpp +++ b/core/Database.cpp @@ -351,6 +351,7 @@ void DBManager::RemoveDriver(IDBDriver *pDriver) { IDBThreadOperation *op = (*qiter); op->CancelThinkPart(); + op->Destroy(); } } @@ -488,8 +489,15 @@ void DBManager::KillWorkerThread() } } +static IdentityToken_t *s_pAddBlock = NULL; + bool DBManager::AddToThreadQueue(IDBThreadOperation *op, PrioQueueLevel prio) { + if (s_pAddBlock && op->GetOwner() == s_pAddBlock) + { + return false; + } + if (!m_pWorker) { m_pWorker = g_pThreader->MakeWorker(this, true); @@ -599,6 +607,7 @@ void DBManager::RunFrame() m_ThinkQueue.pop(); m_pThinkLock->Unlock(); op->RunThinkPart(); + op->Destroy(); } void DBManager::OnTerminate(IThreadHandle *pThread, bool cancel) @@ -606,6 +615,43 @@ void DBManager::OnTerminate(IThreadHandle *pThread, bool cancel) /* Do nothing */ } +void DBManager::OnSourceModIdentityDropped(IdentityToken_t *pToken) +{ + s_pAddBlock = pToken; + + /* Kill the thread so we can flush everything into the think queue... */ + KillWorkerThread(); + + /* Run all of the think operations. + * Unlike the driver unloading example, we'll let these calls go through, + * since a plugin unloading is far more normal. + */ + Queue::iterator iter = m_ThinkQueue.begin(); + Queue templist; + while (iter != m_ThinkQueue.end()) + { + IDBThreadOperation *op = (*iter); + if (op->GetOwner() == pToken) + { + templist.push(op); + iter = m_ThinkQueue.erase(iter); + } else { + iter++; + } + } + + for (iter = templist.begin(); + iter != templist.end(); + iter++) + { + IDBThreadOperation *op = (*iter); + op->RunThinkPart(); + op->Destroy(); + } + + s_pAddBlock = NULL; +} + void DBManager::OnPluginUnloaded(IPlugin *plugin) { /* Kill the thread so we can flush everything into the think queue... */ @@ -623,7 +669,7 @@ void DBManager::OnPluginUnloaded(IPlugin *plugin) while (iter != m_ThinkQueue.end()) { IDBThreadOperation *op = (*iter); - if (op->GetPlugin() == plugin) + if (op->GetOwner() == plugin->GetIdentity()) { templist.push(op); iter = m_ThinkQueue.erase(iter); @@ -638,6 +684,7 @@ void DBManager::OnPluginUnloaded(IPlugin *plugin) { IDBThreadOperation *op = (*iter); op->RunThinkPart(); + op->Destroy(); } } diff --git a/core/Database.h b/core/Database.h index 66647e19..251f1cdb 100644 --- a/core/Database.h +++ b/core/Database.h @@ -44,16 +44,6 @@ struct ConfDbInfo DatabaseInfo info; }; -class IDBThreadOperation -{ -public: - virtual IDBDriver *GetDriver() =0; - virtual CPlugin *GetPlugin() =0; - virtual void RunThreadPart() =0; - virtual void RunThinkPart() =0; - virtual void CancelThinkPart() =0; -}; - class DBManager : public IDBManager, public SMGlobalClass, @@ -71,6 +61,7 @@ public: public: //SMGlobalClass void OnSourceModAllInitialized(); void OnSourceModLevelChange(const char *mapName); + void OnSourceModIdentityDropped(IdentityToken_t *pToken); void OnSourceModShutdown(); public: //IHandleTypeDispatch void OnHandleDestroy(HandleType_t type, void *object); diff --git a/core/sm_globals.h b/core/sm_globals.h index b01e9be3..51c55737 100644 --- a/core/sm_globals.h +++ b/core/sm_globals.h @@ -56,6 +56,7 @@ class SMGlobalClass friend class SourceMod_Core; friend class SourceModBase; friend class CoreConfig; + friend class CExtensionManager; public: SMGlobalClass(); public: @@ -135,6 +136,13 @@ public: virtual void OnSourceModGameInitialized() { } + + /** + * @brief Called when an identity is dropped (right now, extensions only) + */ + virtual void OnSourceModIdentityDropped(IdentityToken_t *pToken) + { + } private: SMGlobalClass *m_pGlobalClassNext; static SMGlobalClass *head; diff --git a/core/sm_simple_prioqueue.h b/core/sm_simple_prioqueue.h index 7e3fe08b..e9b1d4f9 100644 --- a/core/sm_simple_prioqueue.h +++ b/core/sm_simple_prioqueue.h @@ -13,13 +13,7 @@ */ #include "sm_queue.h" - -enum PrioQueueLevel -{ - PrioQueue_High, - PrioQueue_Normal, - PrioQueue_Low -}; +#include template class PrioQueue diff --git a/core/smn_database.cpp b/core/smn_database.cpp index f0bb7de5..d524cbb8 100644 --- a/core/smn_database.cpp +++ b/core/smn_database.cpp @@ -138,9 +138,9 @@ public: m_pDatabase->Close(); } } - CPlugin *GetPlugin() + IdentityToken_t *GetOwner() { - return me; + return me->GetIdentity(); } IDBDriver *GetDriver() { @@ -163,7 +163,6 @@ public: m_pFunction->PushString("Driver is unloading"); m_pFunction->PushCell(m_Data); m_pFunction->Execute(NULL); - delete this; } void RunThinkPart() { @@ -196,7 +195,9 @@ public: { g_HandleSys.FreeHandle(qh, &sec); } - + } + void Destroy() + { delete this; } private: @@ -222,9 +223,9 @@ public: strncopy(dbname, _dbname, sizeof(dbname)); me = g_PluginSys.GetPluginByCtx(m_pFunction->GetParentContext()->GetContext()); } - CPlugin *GetPlugin() + IdentityToken_t *GetOwner() { - return me; + return me->GetIdentity(); } IDBDriver *GetDriver() { @@ -253,7 +254,6 @@ public: m_pFunction->PushString("Driver is unloading"); m_pFunction->PushCell(0); m_pFunction->Execute(NULL); - delete this; } void RunThinkPart() { @@ -274,6 +274,9 @@ public: m_pFunction->PushString(hndl == BAD_HANDLE ? error : ""); m_pFunction->PushCell(0); m_pFunction->Execute(NULL); + } + void Destroy() + { delete this; } private: @@ -382,6 +385,7 @@ static cell_t SQL_TConnect(IPluginContext *pContext, const cell_t *params) /* Do everything right now */ op->RunThreadPart(); op->RunThinkPart(); + op->Destroy(); } return 1; @@ -699,6 +703,7 @@ static cell_t SQL_TQuery(IPluginContext *pContext, const cell_t *params) /* Do everything right now */ op->RunThreadPart(); op->RunThinkPart(); + op->Destroy(); } return 1; diff --git a/core/systems/ExtensionSys.cpp b/core/systems/ExtensionSys.cpp index 0f45f27c..d515a8e9 100644 --- a/core/systems/ExtensionSys.cpp +++ b/core/systems/ExtensionSys.cpp @@ -689,6 +689,17 @@ bool CExtensionManager::UnloadExtension(IExtension *_pExt) } } + IdentityToken_t *pIdentity; + if ((pIdentity = pExt->GetIdentity()) != NULL) + { + SMGlobalClass *glob = SMGlobalClass::head; + while (glob) + { + glob->OnSourceModIdentityDropped(pIdentity); + glob = glob->m_pGlobalClassNext; + } + } + delete pExt; List::iterator iter;