Fix various problems with unloading ClientPrefs and SourceMod (bug 5874, r=ds).

--HG--
extra : rebase_source : 0a35f8380d651ca65fac9dd402c5cd3625e3105c
This commit is contained in:
David Anderson
2013-08-22 14:05:44 -07:00
parent d79b41e4a7
commit 94d33a4ef1
17 changed files with 195 additions and 183 deletions
+2 -28
View File
@@ -1,5 +1,5 @@
/**
* vim: set ts=4 :
* vim: set ts=4 sw=4 tw=99 noet:
* =============================================================================
* SourceMod Client Preferences Extension
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
@@ -55,35 +55,12 @@ void CookieManager::Unload()
for (int i = playerhelpers->GetMaxClients()+1; --i > 0;)
{
if (connected[i])
{
OnClientDisconnecting(i);
}
}
/* Find all cookies and delete them */
Cookie *current;
for (SourceHook::List<Cookie *>::iterator _iter = cookieList.begin(); _iter != cookieList.end(); _iter++)
{
current = (Cookie *)*_iter;
if (current == NULL)
{
continue;
}
g_ClientPrefs.cookieMutex->Lock();
if (current->usedInQuery)
{
current->shouldDelete = true;
g_ClientPrefs.cookieMutex->Unlock();
}
else
{
g_ClientPrefs.cookieMutex->Unlock();
delete current;
}
}
delete (*_iter);
cookieList.clear();
}
@@ -93,9 +70,7 @@ Cookie *CookieManager::FindCookie(const char *name)
Cookie **pCookie = cookieTrie.retrieve(name);
if (pCookie == NULL)
{
return NULL;
}
return *pCookie;
}
@@ -116,7 +91,6 @@ Cookie *CookieManager::CreateCookie(const char *name, const char *description, C
/* First time cookie - Create from scratch */
pCookie = new Cookie(name, description, access);
pCookie->usedInQuery++;
/* Attempt to insert cookie into the db and get its ID num */
TQueryOp *op = new TQueryOp(Query_InsertCookie, pCookie);
-11
View File
@@ -75,12 +75,7 @@ struct Cookie
dbid = -1;
for (int i=0; i<=MAXCLIENTS; i++)
{
data[i] = NULL;
}
shouldDelete = false;
usedInQuery = 0;
}
~Cookie()
@@ -88,9 +83,7 @@ struct Cookie
for (int i=0; i<=MAXCLIENTS; i++)
{
if (data[i] != NULL)
{
delete data[i];
}
}
}
@@ -99,10 +92,6 @@ struct Cookie
int dbid;
CookieData *data[MAXCLIENTS+1];
CookieAccess access;
/* Reference counting stuff */
bool shouldDelete;
int usedInQuery;
};
class CookieManager : public IClientListener, public IPluginsListener
+26 -38
View File
@@ -1,5 +1,5 @@
/**
* vim: set ts=4 :
* vim: set ts=4 sw=4 tw=99 noet:
* =============================================================================
* SourceMod Client Preferences Extension
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
@@ -50,9 +50,6 @@ DbDriver g_DriverType;
bool ClientPrefs::SDK_OnLoad(char *error, size_t maxlength, bool late)
{
queryMutex = threader->MakeMutex();
cookieMutex = threader->MakeMutex();
DBInfo = dbi->FindDatabaseConf("clientprefs");
if (DBInfo == NULL)
@@ -155,13 +152,15 @@ void ClientPrefs::NotifyInterfaceDrop(SMInterface *pInterface)
}
}
void ClientPrefs::SDK_OnUnload()
void ClientPrefs::SDK_OnDependenciesDropped()
{
// At this point, we're guaranteed that DBI has flushed the worker thread
// for us, so no cookies should have outstanding queries.
g_CookieManager.Unload();
handlesys->RemoveType(g_CookieType, myself->GetIdentity());
handlesys->RemoveType(g_CookieIterator, myself->GetIdentity());
g_CookieManager.Unload();
if (Database != NULL)
{
Database->Close();
@@ -199,9 +198,6 @@ void ClientPrefs::SDK_OnUnload()
plsys->RemovePluginsListener(&g_CookieManager);
playerhelpers->RemoveClientListener(&g_CookieManager);
queryMutex->DestroyThis();
cookieMutex->DestroyThis();
}
void ClientPrefs::OnCoreMapStart(edict_t *pEdictList, int edictCount, int clientMax)
@@ -312,7 +308,11 @@ void ClientPrefs::DatabaseConnect()
databaseLoading = false;
this->ProcessQueryCache();
// Need a new scope because of the goto above.
{
ke::AutoLock lock(&queryLock);
this->ProcessQueryCache();
}
return;
fatal_fail:
@@ -321,24 +321,18 @@ fatal_fail:
databaseLoading = false;
}
bool ClientPrefs::AddQueryToQueue( TQueryOp *query )
bool ClientPrefs::AddQueryToQueue(TQueryOp *query)
{
queryMutex->Lock();
if (Database == NULL)
{
cachedQueries.push_back(query);
queryMutex->Unlock();
return false;
}
if (!cachedQueries.empty())
{
queryMutex->Unlock();
this->ProcessQueryCache();
}
else
{
queryMutex->Unlock();
ke::AutoLock lock(&queryLock);
if (Database == NULL)
{
cachedQueries.push_back(query);
return false;
}
if (!cachedQueries.empty())
this->ProcessQueryCache();
}
query->SetDatabase(Database);
@@ -348,12 +342,11 @@ bool ClientPrefs::AddQueryToQueue( TQueryOp *query )
void ClientPrefs::ProcessQueryCache()
{
if (Database == NULL)
{
return;
}
queryLock.AssertCurrentThreadOwns();
if (Database == NULL)
return;
queryMutex->Lock();
TQueryOp *op;
for (SourceHook::List<TQueryOp *>::iterator iter = cachedQueries.begin(); iter != cachedQueries.end(); iter++)
{
@@ -363,7 +356,6 @@ void ClientPrefs::ProcessQueryCache()
}
cachedQueries.clear();
queryMutex->Unlock();
}
size_t IsAuthIdConnected(char *authID)
@@ -417,8 +409,7 @@ void ClientPrefs::CatchLateLoadClients()
void ClientPrefs::ClearQueryCache(int serial)
{
queryMutex->Lock();
ke::AutoLock lock(&queryLock);
for (SourceHook::List<TQueryOp *>::iterator iter = cachedQueries.begin(); iter != cachedQueries.end();)
{
TQueryOp *op = *iter;
@@ -432,7 +423,6 @@ void ClientPrefs::ClearQueryCache(int serial)
iter++;
}
}
queryMutex->Unlock();
}
bool Translate(char *buffer,
@@ -530,7 +520,5 @@ ClientPrefs::ClientPrefs()
phrases = NULL;
DBInfo = NULL;
cookieMutex = NULL;
queryMutex = NULL;
identity = NULL;
}
+6 -7
View File
@@ -1,5 +1,5 @@
/**
* vim: set ts=4 :
* vim: set ts=4 sw=4 tw=99 noet:
* =============================================================================
* SourceMod Client Preferences Extension
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
@@ -39,6 +39,8 @@
#include "smsdk_ext.h"
#include "sh_list.h"
#include <ke_thread_utils.h>
char * UTIL_strncpy(char * destination, const char * source, size_t num);
#include "cookie.h"
@@ -73,11 +75,8 @@ public:
* @return True to succeed loading, false to fail.
*/
virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late);
/**
* @brief This is called right before the extension is unloaded.
*/
virtual void SDK_OnUnload();
virtual void SDK_OnDependenciesDropped();
/**
* @brief This is called once all known extensions have been loaded.
@@ -162,7 +161,7 @@ public:
private:
SourceHook::List<TQueryOp *> cachedQueries;
IMutex *queryMutex;
ke::Mutex queryLock;
IdentityToken_t *identity;
};
-17
View File
@@ -303,23 +303,6 @@ int TQueryOp::PullQuerySerial()
ParamData::~ParamData()
{
if (cookie)
{
g_ClientPrefs.cookieMutex->Lock();
cookie->usedInQuery--;
if (cookie->shouldDelete && cookie->usedInQuery <= 0)
{
g_ClientPrefs.cookieMutex->Unlock();
delete cookie;
cookie = NULL;
}
else
{
g_ClientPrefs.cookieMutex->Unlock();
}
}
if (data)
{
/* Data is only ever passed in a client disconnect query and always needs to be deleted */
+1 -1
View File
@@ -67,7 +67,7 @@
//#define SMEXT_ENABLE_MEMUTILS
#define SMEXT_ENABLE_GAMEHELPERS
//#define SMEXT_ENABLE_TIMERSYS
#define SMEXT_ENABLE_THREADER
//#define SMEXT_ENABLE_THREADER
//#define SMEXT_ENABLE_LIBSYS
#define SMEXT_ENABLE_MENUS
//#define SMEXT_ENABLE_ADTFACTORY
+22 -1
View File
@@ -1,5 +1,5 @@
/**
* vim: set ts=4 :
* vim: set ts=4 sw=4 tw=99 noet:
* =============================================================================
* SourceMod Base Extension Code
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
@@ -97,6 +97,12 @@ IUserMessages *usermsgs = NULL;
#if defined SMEXT_ENABLE_TRANSLATOR
ITranslator *translator = NULL;
#endif
#if defined SMEXT_ENABLE_NINVOKE
INativeInterface *ninvoke = NULL;
#endif
#if defined SMEXT_ENABLE_ROOTCONSOLEMENU
IRootConsole *rootconsole = NULL;
#endif
/** Exports the main interface */
PLATFORM_EXTERN_C IExtensionInterface *GetSMExtAPI()
@@ -185,6 +191,12 @@ bool SDKExtension::OnExtensionLoad(IExtension *me, IShareSys *sys, char *error,
#if defined SMEXT_ENABLE_TRANSLATOR
SM_GET_IFACE(TRANSLATOR, translator);
#endif
#if defined SMEXT_ENABLE_NINVOKE
SM_GET_IFACE(NINVOKE, ninvoke);
#endif
#if defined SMEXT_ENABLE_ROOTCONSOLEMENU
SM_GET_IFACE(ROOTCONSOLE, rootconsole);
#endif
if (SDK_OnLoad(error, maxlength, late))
{
@@ -227,6 +239,11 @@ void SDKExtension::OnExtensionUnload()
SDK_OnUnload();
}
void SDKExtension::OnDependenciesDropped()
{
SDK_OnDependenciesDropped();
}
const char *SDKExtension::GetExtensionAuthor()
{
return SMEXT_CONF_AUTHOR;
@@ -279,6 +296,10 @@ void SDKExtension::SDK_OnAllLoaded()
{
}
void SDKExtension::SDK_OnDependenciesDropped()
{
}
#if defined SMEXT_CONF_METAMOD
PluginId g_PLID = 0; /**< Metamod plugin ID */
+23 -2
View File
@@ -1,5 +1,5 @@
/**
* vim: set ts=4 :
* vim: set ts=4 sw=4 tw=99 noet:
* =============================================================================
* SourceMod Base Extension Code
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
@@ -91,6 +91,12 @@
#if defined SMEXT_ENABLE_TRANSLATOR
#include <ITranslator.h>
#endif
#if defined SMEXT_ENABLE_NINVOKE
#include <INativeInvoker.h>
#endif
#if defined SMEXT_ENABLE_ROOTCONSOLEMENU
#include <IRootConsoleMenu.h>
#endif
#if defined SMEXT_CONF_METAMOD
#include <ISmmPlugin.h>
@@ -121,7 +127,7 @@ public:
virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late);
/**
* @brief This is called right before the extension is unloaded.
* @brief This is called once the extension unloading process begins.
*/
virtual void SDK_OnUnload();
@@ -135,6 +141,12 @@ public:
*/
virtual void SDK_OnPauseChange(bool paused);
/**
* @brief Called after SDK_OnUnload, once all dependencies have been
* removed, and the extension is about to be removed from memory.
*/
virtual void SDK_OnDependenciesDropped();
#if defined SMEXT_CONF_METAMOD
/**
* @brief Called when Metamod is attached, before the extension version is called.
@@ -197,6 +209,9 @@ public: //IExtensionInterface
virtual const char *GetExtensionDescription();
/** Returns date string */
virtual const char *GetExtensionDateString();
/** Called after OnExtensionUnload, once dependencies have been dropped. */
virtual void OnDependenciesDropped();
#if defined SMEXT_CONF_METAMOD
public: //ISmmPlugin
/** Called when the extension is attached to Metamod. */
@@ -289,6 +304,12 @@ extern IUserMessages *usermsgs;
#if defined SMEXT_ENABLE_TRANSLATOR
extern ITranslator *translator;
#endif
#if defined SMEXT_ENABLE_NINVOKE
extern INativeInterface *ninvoke;
#endif
#if defined SMEXT_ENABLE_ROOTCONSOLEMENU
extern IRootConsole *rootconsole;
#endif
#if defined SMEXT_CONF_METAMOD
PLUGIN_GLOBALVARS();