Add reference counting to IDatabase (bug 5876 part 2, r=ds).

--HG--
extra : rebase_source : 9fef982c3923a2f5cb842b3b8a5cca235ef9c6b9
This commit is contained in:
David Anderson 2013-08-23 00:18:12 -07:00
parent f7991185ba
commit dac42ee272
5 changed files with 33 additions and 36 deletions

View File

@ -32,6 +32,8 @@
#include <sourcemod_version.h> #include <sourcemod_version.h>
#include "extension.h" #include "extension.h"
using namespace ke;
/** /**
* @file extension.cpp * @file extension.cpp
* @brief Implement extension code here. * @brief Implement extension code here.
@ -145,11 +147,8 @@ bool ClientPrefs::QueryInterfaceDrop(SMInterface *pInterface)
void ClientPrefs::NotifyInterfaceDrop(SMInterface *pInterface) void ClientPrefs::NotifyInterfaceDrop(SMInterface *pInterface)
{ {
if (Database != NULL && (void *)pInterface == (void *)(Database->GetDriver())) if (Database && (void *)pInterface == (void *)(Database->GetDriver()))
{
Database->Close();
Database = NULL; Database = NULL;
}
} }
void ClientPrefs::SDK_OnDependenciesDropped() void ClientPrefs::SDK_OnDependenciesDropped()
@ -161,11 +160,7 @@ void ClientPrefs::SDK_OnDependenciesDropped()
handlesys->RemoveType(g_CookieType, myself->GetIdentity()); handlesys->RemoveType(g_CookieType, myself->GetIdentity());
handlesys->RemoveType(g_CookieIterator, myself->GetIdentity()); handlesys->RemoveType(g_CookieIterator, myself->GetIdentity());
if (Database != NULL) Database = NULL;
{
Database->Close();
Database = NULL;
}
if (g_CookieManager.cookieDataLoadedForward != NULL) if (g_CookieManager.cookieDataLoadedForward != NULL)
{ {
@ -208,9 +203,7 @@ void ClientPrefs::OnCoreMapStart(edict_t *pEdictList, int edictCount, int client
void ClientPrefs::AttemptReconnection() void ClientPrefs::AttemptReconnection()
{ {
if (Database || databaseLoading) if (Database || databaseLoading)
{
return; /* We're already loading, or have loaded. */ return; /* We're already loading, or have loaded. */
}
g_pSM->LogMessage(myself, "Attempting to reconnect to database..."); g_pSM->LogMessage(myself, "Attempting to reconnect to database...");
databaseLoading = true; databaseLoading = true;
@ -226,9 +219,9 @@ void ClientPrefs::DatabaseConnect()
char error[256]; char error[256];
int errCode = 0; int errCode = 0;
Database = Driver->Connect(DBInfo, true, error, sizeof(error)); Database = Newborn<IDatabase>(Driver->Connect(DBInfo, true, error, sizeof(error)));
if (Database == NULL) if (!Database)
{ {
g_pSM->LogError(myself, error); g_pSM->LogError(myself, error);
databaseLoading = false; databaseLoading = false;
@ -310,13 +303,12 @@ void ClientPrefs::DatabaseConnect()
// Need a new scope because of the goto above. // Need a new scope because of the goto above.
{ {
ke::AutoLock lock(&queryLock); AutoLock lock(&queryLock);
this->ProcessQueryCache(); this->ProcessQueryCache();
} }
return; return;
fatal_fail: fatal_fail:
Database->Close();
Database = NULL; Database = NULL;
databaseLoading = false; databaseLoading = false;
} }
@ -324,8 +316,8 @@ fatal_fail:
bool ClientPrefs::AddQueryToQueue(TQueryOp *query) bool ClientPrefs::AddQueryToQueue(TQueryOp *query)
{ {
{ {
ke::AutoLock lock(&queryLock); AutoLock lock(&queryLock);
if (Database == NULL) if (!Database)
{ {
cachedQueries.push_back(query); cachedQueries.push_back(query);
return false; return false;
@ -344,7 +336,7 @@ void ClientPrefs::ProcessQueryCache()
{ {
queryLock.AssertCurrentThreadOwns(); queryLock.AssertCurrentThreadOwns();
if (Database == NULL) if (!Database)
return; return;
TQueryOp *op; TQueryOp *op;
@ -409,7 +401,7 @@ void ClientPrefs::CatchLateLoadClients()
void ClientPrefs::ClearQueryCache(int serial) void ClientPrefs::ClearQueryCache(int serial)
{ {
ke::AutoLock lock(&queryLock); AutoLock lock(&queryLock);
for (SourceHook::List<TQueryOp *>::iterator iter = cachedQueries.begin(); iter != cachedQueries.end();) for (SourceHook::List<TQueryOp *>::iterator iter = cachedQueries.begin(); iter != cachedQueries.end();)
{ {
TQueryOp *op = *iter; TQueryOp *op = *iter;
@ -515,7 +507,6 @@ const char *ClientPrefs::GetExtensionDateString()
ClientPrefs::ClientPrefs() ClientPrefs::ClientPrefs()
{ {
Driver = NULL; Driver = NULL;
Database = NULL;
databaseLoading = false; databaseLoading = false;
phrases = NULL; phrases = NULL;
DBInfo = NULL; DBInfo = NULL;

View File

@ -40,6 +40,7 @@
#include "sh_list.h" #include "sh_list.h"
#include <am-thread-utils.h> #include <am-thread-utils.h>
#include <am-refcounting.h>
char * UTIL_strncpy(char * destination, const char * source, size_t num); char * UTIL_strncpy(char * destination, const char * source, size_t num);
@ -152,7 +153,7 @@ public:
IdentityToken_t *GetIdentity() const; IdentityToken_t *GetIdentity() const;
public: public:
IDBDriver *Driver; IDBDriver *Driver;
IDatabase *Database; ke::Ref<IDatabase> Database;
IPhraseCollection *phrases; IPhraseCollection *phrases;
const DatabaseInfo *DBInfo; const DatabaseInfo *DBInfo;

View File

@ -131,7 +131,6 @@ TQueryOp::TQueryOp(enum querytype type, Cookie *cookie)
void TQueryOp::SetDatabase(IDatabase *db) void TQueryOp::SetDatabase(IDatabase *db)
{ {
m_database = db; m_database = db;
m_database->IncReferenceCount();
} }
bool TQueryOp::BindParamsAndRun() bool TQueryOp::BindParamsAndRun()

View File

@ -1,5 +1,5 @@
/** /**
* vim: set ts=4 : * vim: set ts=4 sw=4 tw=99 noet :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
@ -607,6 +607,20 @@ namespace SourceMod
* @param characterset The characterset to switch to. e.g. "utf8". * @param characterset The characterset to switch to. e.g. "utf8".
*/ */
virtual bool SetCharacterSet(const char *characterset) =0; virtual bool SetCharacterSet(const char *characterset) =0;
/**
* @brief Wrapper around IncReferenceCount(), for ke::Ref.
*/
void AddRef() {
IncReferenceCount();
}
/**
* @brief Wrapper around Close(), for ke::Ref.
*/
void Release() {
Close();
}
}; };
/** /**

View File

@ -44,19 +44,17 @@ template <typename T>
class Newborn class Newborn
{ {
public: public:
Newborn(const T &t) Newborn(T *t)
: thing_(t) : thing_(t)
{ {
} }
T release() const { T *release() const {
T temp = thing_; return ReturnAndVoid(thing_);
thing_ = T();
return temp;
} }
private: private:
mutable T thing_; mutable T *thing_;
}; };
// When returning a value, we'd rather not be needlessly changing the refcount, // When returning a value, we'd rather not be needlessly changing the refcount,
@ -110,9 +108,6 @@ class PassRef
T *operator *() const { T *operator *() const {
return thing_; return thing_;
} }
operator bool () const {
return !!thing_;
}
bool operator !() const { bool operator !() const {
return !thing_; return !thing_;
} }
@ -209,7 +204,7 @@ class Ref
: thing_(other.release()) : thing_(other.release())
{ {
} }
Ref(const Newborn<T *> &other) Ref(const Newborn<T> &other)
: thing_(other.release()) : thing_(other.release())
{ {
} }
@ -227,9 +222,6 @@ class Ref
operator T *() { operator T *() {
return thing_; return thing_;
} }
operator bool () const {
return !!thing_;
}
bool operator !() const { bool operator !() const {
return !thing_; return !thing_;
} }