Add atomic reference counting and port DBI (bug 5876 part 3, r=ds).
--HG-- extra : rebase_source : a6defaf477e7a856ce91f92d5f3143f12c141da3
This commit is contained in:
parent
dac42ee272
commit
4d43374fde
@ -306,7 +306,6 @@ DBResult MyBasicResults::CopyBlob(unsigned int columnId, void *buffer, size_t ma
|
|||||||
MyQuery::MyQuery(MyDatabase *db, MYSQL_RES *res)
|
MyQuery::MyQuery(MyDatabase *db, MYSQL_RES *res)
|
||||||
: m_pParent(db), m_rs(res)
|
: m_pParent(db), m_rs(res)
|
||||||
{
|
{
|
||||||
m_pParent->IncReferenceCount();
|
|
||||||
m_InsertID = m_pParent->GetInsertID();
|
m_InsertID = m_pParent->GetInsertID();
|
||||||
m_AffectedRows = m_pParent->GetAffectedRows();
|
m_AffectedRows = m_pParent->GetAffectedRows();
|
||||||
}
|
}
|
||||||
@ -371,9 +370,6 @@ void MyQuery::Destroy()
|
|||||||
mysql_free_result(m_rs.m_pRes);
|
mysql_free_result(m_rs.m_pRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tell our parent we're done */
|
|
||||||
m_pParent->Close();
|
|
||||||
|
|
||||||
/* Self destruct */
|
/* Self destruct */
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 :
|
* vim: set ts=4 sw=4 tw=99 noet :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod MySQL Extension
|
* SourceMod MySQL Extension
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@ -91,7 +91,7 @@ public: // Used by the driver to implement GetInsertIDForQuery()/GetAffectedRows
|
|||||||
unsigned int GetInsertID();
|
unsigned int GetInsertID();
|
||||||
unsigned int GetAffectedRows();
|
unsigned int GetAffectedRows();
|
||||||
private:
|
private:
|
||||||
MyDatabase *m_pParent;
|
ke::Ref<MyDatabase> m_pParent;
|
||||||
MyBasicResults m_rs;
|
MyBasicResults m_rs;
|
||||||
unsigned int m_InsertID;
|
unsigned int m_InsertID;
|
||||||
unsigned int m_AffectedRows;
|
unsigned int m_AffectedRows;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 :
|
* vim: set ts=4 sw=4 tw=99 noet :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod MySQL Extension
|
* SourceMod MySQL Extension
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@ -87,7 +87,7 @@ DBType GetOurType(enum_field_types type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
MyDatabase::MyDatabase(MYSQL *mysql, const DatabaseInfo *info, bool persistent)
|
MyDatabase::MyDatabase(MYSQL *mysql, const DatabaseInfo *info, bool persistent)
|
||||||
: m_mysql(mysql), m_refcount(1), m_pFullLock(NULL), m_bPersistent(persistent)
|
: m_mysql(mysql), m_bPersistent(persistent)
|
||||||
{
|
{
|
||||||
m_Host.assign(info->host);
|
m_Host.assign(info->host);
|
||||||
m_Database.assign(info->database);
|
m_Database.assign(info->database);
|
||||||
@ -101,50 +101,24 @@ MyDatabase::MyDatabase(MYSQL *mysql, const DatabaseInfo *info, bool persistent)
|
|||||||
m_Info.driver = NULL;
|
m_Info.driver = NULL;
|
||||||
m_Info.maxTimeout = info->maxTimeout;
|
m_Info.maxTimeout = info->maxTimeout;
|
||||||
m_Info.port = info->port;
|
m_Info.port = info->port;
|
||||||
|
|
||||||
m_pRefLock = threader->MakeMutex();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MyDatabase::~MyDatabase()
|
MyDatabase::~MyDatabase()
|
||||||
{
|
{
|
||||||
|
/* Remove us from the search list */
|
||||||
|
if (m_bPersistent)
|
||||||
|
g_MyDriver.RemoveFromList(this, true);
|
||||||
mysql_close(m_mysql);
|
mysql_close(m_mysql);
|
||||||
m_mysql = NULL;
|
|
||||||
|
|
||||||
m_pRefLock->DestroyThis();
|
|
||||||
if (m_pFullLock)
|
|
||||||
{
|
|
||||||
m_pFullLock->DestroyThis();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyDatabase::IncReferenceCount()
|
void MyDatabase::IncReferenceCount()
|
||||||
{
|
{
|
||||||
m_pRefLock->Lock();
|
AddRef();
|
||||||
m_refcount++;
|
|
||||||
m_pRefLock->Unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MyDatabase::Close()
|
bool MyDatabase::Close()
|
||||||
{
|
{
|
||||||
m_pRefLock->Lock();
|
return !Release();
|
||||||
if (m_refcount > 1)
|
|
||||||
{
|
|
||||||
m_refcount--;
|
|
||||||
m_pRefLock->Unlock();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
m_pRefLock->Unlock();
|
|
||||||
|
|
||||||
/* Remove us from the search list */
|
|
||||||
if (m_bPersistent)
|
|
||||||
{
|
|
||||||
g_MyDriver.RemoveFromList(this, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Finally, free our resource(s) */
|
|
||||||
delete this;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const DatabaseInfo &MyDatabase::GetInfo()
|
const DatabaseInfo &MyDatabase::GetInfo()
|
||||||
@ -300,26 +274,17 @@ IPreparedQuery *MyDatabase::PrepareQuery(const char *query, char *error, size_t
|
|||||||
|
|
||||||
bool MyDatabase::LockForFullAtomicOperation()
|
bool MyDatabase::LockForFullAtomicOperation()
|
||||||
{
|
{
|
||||||
if (!m_pFullLock)
|
if (!m_FullLock)
|
||||||
{
|
m_FullLock = new ke::Mutex();
|
||||||
m_pFullLock = threader->MakeMutex();
|
|
||||||
if (!m_pFullLock)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pFullLock->Lock();
|
|
||||||
|
|
||||||
|
m_FullLock->Lock();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyDatabase::UnlockFromFullAtomicOperation()
|
void MyDatabase::UnlockFromFullAtomicOperation()
|
||||||
{
|
{
|
||||||
if (m_pFullLock)
|
if (m_FullLock)
|
||||||
{
|
m_FullLock->Unlock();
|
||||||
m_pFullLock->Unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IDBDriver *MyDatabase::GetDriver()
|
IDBDriver *MyDatabase::GetDriver()
|
||||||
@ -330,4 +295,4 @@ IDBDriver *MyDatabase::GetDriver()
|
|||||||
bool MyDatabase::SetCharacterSet(const char *characterset)
|
bool MyDatabase::SetCharacterSet(const char *characterset)
|
||||||
{
|
{
|
||||||
return mysql_set_character_set(m_mysql, characterset) == 0 ? true : false;
|
return mysql_set_character_set(m_mysql, characterset) == 0 ? true : false;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 :
|
* vim: set ts=4 sw=4 tw=99 noet :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod MySQL Extension
|
* SourceMod MySQL Extension
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@ -32,13 +32,16 @@
|
|||||||
#ifndef _INCLUDE_SM_MYSQL_DATABASE_H_
|
#ifndef _INCLUDE_SM_MYSQL_DATABASE_H_
|
||||||
#define _INCLUDE_SM_MYSQL_DATABASE_H_
|
#define _INCLUDE_SM_MYSQL_DATABASE_H_
|
||||||
|
|
||||||
|
#include <am-thread-utils.h>
|
||||||
|
#include <am-refcounting-threadsafe.h>
|
||||||
#include "MyDriver.h"
|
#include "MyDriver.h"
|
||||||
#include <IThreader.h>
|
|
||||||
|
|
||||||
class MyQuery;
|
class MyQuery;
|
||||||
class MyStatement;
|
class MyStatement;
|
||||||
|
|
||||||
class MyDatabase : public IDatabase
|
class MyDatabase
|
||||||
|
: public IDatabase,
|
||||||
|
public ke::RefcountedThreadsafe<MyDatabase>
|
||||||
{
|
{
|
||||||
friend class MyQuery;
|
friend class MyQuery;
|
||||||
friend class MyStatement;
|
friend class MyStatement;
|
||||||
@ -67,9 +70,7 @@ public:
|
|||||||
const DatabaseInfo &GetInfo();
|
const DatabaseInfo &GetInfo();
|
||||||
private:
|
private:
|
||||||
MYSQL *m_mysql;
|
MYSQL *m_mysql;
|
||||||
unsigned int m_refcount;
|
ke::AutoPtr<ke::Mutex> m_FullLock;
|
||||||
IMutex *m_pFullLock;
|
|
||||||
IMutex *m_pRefLock;
|
|
||||||
|
|
||||||
/* ---------- */
|
/* ---------- */
|
||||||
DatabaseInfo m_Info;
|
DatabaseInfo m_Info;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 :
|
* vim: set ts=4 sw=4 tw=99 noet :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod MySQL Extension
|
* SourceMod MySQL Extension
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@ -154,6 +154,8 @@ bool CompareField(const char *str1, const char *str2)
|
|||||||
|
|
||||||
IDatabase *MyDriver::Connect(const DatabaseInfo *info, bool persistent, char *error, size_t maxlength)
|
IDatabase *MyDriver::Connect(const DatabaseInfo *info, bool persistent, char *error, size_t maxlength)
|
||||||
{
|
{
|
||||||
|
ke::AutoLock lock(&m_Lock);
|
||||||
|
|
||||||
if (persistent)
|
if (persistent)
|
||||||
{
|
{
|
||||||
/* Try to find a matching persistent connection */
|
/* Try to find a matching persistent connection */
|
||||||
@ -194,6 +196,7 @@ IDatabase *MyDriver::Connect(const DatabaseInfo *info, bool persistent, char *er
|
|||||||
|
|
||||||
void MyDriver::RemoveFromList(MyDatabase *pdb, bool persistent)
|
void MyDriver::RemoveFromList(MyDatabase *pdb, bool persistent)
|
||||||
{
|
{
|
||||||
|
ke::AutoLock lock(&m_Lock);
|
||||||
if (persistent)
|
if (persistent)
|
||||||
{
|
{
|
||||||
m_PermDbs.remove(pdb);
|
m_PermDbs.remove(pdb);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 :
|
* vim: set ts=4 sw=4 tw=99 noet :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod MySQL Extension
|
* SourceMod MySQL Extension
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@ -32,6 +32,7 @@
|
|||||||
#ifndef _INCLUDE_SM_MYSQL_DRIVER_H_
|
#ifndef _INCLUDE_SM_MYSQL_DRIVER_H_
|
||||||
#define _INCLUDE_SM_MYSQL_DRIVER_H_
|
#define _INCLUDE_SM_MYSQL_DRIVER_H_
|
||||||
|
|
||||||
|
#define SOURCEMOD_SQL_DRIVER_CODE
|
||||||
#include <IDBDriver.h>
|
#include <IDBDriver.h>
|
||||||
#include <sm_platform.h>
|
#include <sm_platform.h>
|
||||||
#if defined PLATFORM_WINDOWS
|
#if defined PLATFORM_WINDOWS
|
||||||
@ -46,6 +47,7 @@
|
|||||||
|
|
||||||
#include <sh_string.h>
|
#include <sh_string.h>
|
||||||
#include <sh_list.h>
|
#include <sh_list.h>
|
||||||
|
#include <am-thread-utils.h>
|
||||||
|
|
||||||
using namespace SourceMod;
|
using namespace SourceMod;
|
||||||
using namespace SourceHook;
|
using namespace SourceHook;
|
||||||
@ -71,6 +73,7 @@ public:
|
|||||||
void Shutdown();
|
void Shutdown();
|
||||||
void RemoveFromList(MyDatabase *pdb, bool persistent);
|
void RemoveFromList(MyDatabase *pdb, bool persistent);
|
||||||
private:
|
private:
|
||||||
|
ke::Mutex m_Lock;
|
||||||
Handle_t m_MyHandle;
|
Handle_t m_MyHandle;
|
||||||
List<MyDatabase *> m_TempDbs;
|
List<MyDatabase *> m_TempDbs;
|
||||||
List<MyDatabase *> m_PermDbs;
|
List<MyDatabase *> m_PermDbs;
|
||||||
|
@ -48,8 +48,6 @@ MyStatement::MyStatement(MyDatabase *db, MYSQL_STMT *stmt)
|
|||||||
m_bind = NULL;
|
m_bind = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pParent->IncReferenceCount();
|
|
||||||
|
|
||||||
m_pRes = mysql_stmt_result_metadata(stmt);
|
m_pRes = mysql_stmt_result_metadata(stmt);
|
||||||
m_Results = false;
|
m_Results = false;
|
||||||
}
|
}
|
||||||
@ -75,9 +73,6 @@ MyStatement::~MyStatement()
|
|||||||
mysql_free_result(m_pRes);
|
mysql_free_result(m_pRes);
|
||||||
}
|
}
|
||||||
mysql_stmt_close(m_stmt);
|
mysql_stmt_close(m_stmt);
|
||||||
|
|
||||||
/* Tell the parent database that we're done referencing it */
|
|
||||||
m_pParent->Close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyStatement::Destroy()
|
void MyStatement::Destroy()
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 :
|
* vim: set ts=4 sw=4 tw=99 noet :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod MySQL Extension
|
* SourceMod MySQL Extension
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@ -69,7 +69,7 @@ private:
|
|||||||
void *CopyBlob(unsigned int param, const void *blobptr, size_t length);
|
void *CopyBlob(unsigned int param, const void *blobptr, size_t length);
|
||||||
private:
|
private:
|
||||||
MYSQL *m_mysql;
|
MYSQL *m_mysql;
|
||||||
MyDatabase *m_pParent;
|
ke::Ref<MyDatabase> m_pParent;
|
||||||
MYSQL_STMT *m_stmt;
|
MYSQL_STMT *m_stmt;
|
||||||
MYSQL_BIND *m_bind;
|
MYSQL_BIND *m_bind;
|
||||||
MYSQL_RES *m_pRes;
|
MYSQL_RES *m_pRes;
|
||||||
|
@ -67,6 +67,6 @@
|
|||||||
//#define SMEXT_ENABLE_MEMUTILS
|
//#define SMEXT_ENABLE_MEMUTILS
|
||||||
//#define SMEXT_ENABLE_GAMEHELPERS
|
//#define SMEXT_ENABLE_GAMEHELPERS
|
||||||
//#define SMEXT_ENABLE_TIMERSYS
|
//#define SMEXT_ENABLE_TIMERSYS
|
||||||
#define SMEXT_ENABLE_THREADER
|
//#define SMEXT_ENABLE_THREADER
|
||||||
|
|
||||||
#endif // _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
|
#endif // _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 :
|
* vim: set ts=4 sw=4 tw=99 noet :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod SQLite Extension
|
* SourceMod SQLite Extension
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@ -34,47 +34,25 @@
|
|||||||
#include "SqQuery.h"
|
#include "SqQuery.h"
|
||||||
|
|
||||||
SqDatabase::SqDatabase(sqlite3 *sq3, bool persistent) :
|
SqDatabase::SqDatabase(sqlite3 *sq3, bool persistent) :
|
||||||
m_sq3(sq3), m_refcount(1), m_pFullLock(NULL), m_Persistent(persistent)
|
m_sq3(sq3), m_Persistent(persistent)
|
||||||
{
|
{
|
||||||
m_pRefLock = threader->MakeMutex();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SqDatabase::~SqDatabase()
|
SqDatabase::~SqDatabase()
|
||||||
{
|
{
|
||||||
m_pRefLock->DestroyThis();
|
if (m_Persistent)
|
||||||
if (m_pFullLock)
|
g_SqDriver.RemovePersistent(this);
|
||||||
{
|
|
||||||
m_pFullLock->DestroyThis();
|
|
||||||
}
|
|
||||||
sqlite3_close(m_sq3);
|
sqlite3_close(m_sq3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SqDatabase::IncReferenceCount()
|
void SqDatabase::IncReferenceCount()
|
||||||
{
|
{
|
||||||
m_pRefLock->Lock();
|
AddRef();
|
||||||
m_refcount++;
|
|
||||||
m_pRefLock->Unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SqDatabase::Close()
|
bool SqDatabase::Close()
|
||||||
{
|
{
|
||||||
m_pRefLock->Lock();
|
return !Release();
|
||||||
if (m_refcount > 1)
|
|
||||||
{
|
|
||||||
m_refcount--;
|
|
||||||
m_pRefLock->Unlock();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
m_pRefLock->Unlock();
|
|
||||||
|
|
||||||
if (m_Persistent)
|
|
||||||
{
|
|
||||||
g_SqDriver.RemovePersistent(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete this;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *SqDatabase::GetError(int *errorCode/* =NULL */)
|
const char *SqDatabase::GetError(int *errorCode/* =NULL */)
|
||||||
@ -84,26 +62,17 @@ const char *SqDatabase::GetError(int *errorCode/* =NULL */)
|
|||||||
|
|
||||||
bool SqDatabase::LockForFullAtomicOperation()
|
bool SqDatabase::LockForFullAtomicOperation()
|
||||||
{
|
{
|
||||||
if (!m_pFullLock)
|
if (!m_FullLock)
|
||||||
{
|
m_FullLock = new ke::Mutex();
|
||||||
m_pFullLock = threader->MakeMutex();
|
|
||||||
if (!m_pFullLock)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pFullLock->Lock();
|
|
||||||
|
|
||||||
|
m_FullLock->Lock();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SqDatabase::UnlockFromFullAtomicOperation()
|
void SqDatabase::UnlockFromFullAtomicOperation()
|
||||||
{
|
{
|
||||||
if (m_pFullLock)
|
if (m_FullLock)
|
||||||
{
|
m_FullLock->Unlock();
|
||||||
m_pFullLock->Unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IDBDriver *SqDatabase::GetDriver()
|
IDBDriver *SqDatabase::GetDriver()
|
||||||
@ -259,4 +228,4 @@ bool SqDatabase::SetCharacterSet(const char *characterset)
|
|||||||
{
|
{
|
||||||
// sqlite only supports utf8 and utf16 - by the time the database is created. It's too late here.
|
// sqlite only supports utf8 and utf16 - by the time the database is created. It's too late here.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 :
|
* vim: set ts=4 sw=4 tw=99 noet :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod SQLite Extension
|
* SourceMod SQLite Extension
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@ -32,10 +32,13 @@
|
|||||||
#ifndef _INCLUDE_SQLITE_SOURCEMOD_DATABASE_H_
|
#ifndef _INCLUDE_SQLITE_SOURCEMOD_DATABASE_H_
|
||||||
#define _INCLUDE_SQLITE_SOURCEMOD_DATABASE_H_
|
#define _INCLUDE_SQLITE_SOURCEMOD_DATABASE_H_
|
||||||
|
|
||||||
#include <IThreader.h>
|
#include <am-refcounting-threadsafe.h>
|
||||||
|
#include <am-thread-utils.h>
|
||||||
#include "SqDriver.h"
|
#include "SqDriver.h"
|
||||||
|
|
||||||
class SqDatabase : public IDatabase
|
class SqDatabase
|
||||||
|
: public IDatabase,
|
||||||
|
public ke::RefcountedThreadsafe<SqDatabase>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SqDatabase(sqlite3 *sq3, bool persistent);
|
SqDatabase(sqlite3 *sq3, bool persistent);
|
||||||
@ -63,9 +66,7 @@ public:
|
|||||||
sqlite3 *GetDb();
|
sqlite3 *GetDb();
|
||||||
private:
|
private:
|
||||||
sqlite3 *m_sq3;
|
sqlite3 *m_sq3;
|
||||||
unsigned int m_refcount;
|
ke::AutoPtr<ke::Mutex> m_FullLock;
|
||||||
IMutex *m_pFullLock;
|
|
||||||
IMutex *m_pRefLock;
|
|
||||||
bool m_Persistent;
|
bool m_Persistent;
|
||||||
String m_LastError;
|
String m_LastError;
|
||||||
int m_LastErrorCode;
|
int m_LastErrorCode;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 :
|
* vim: set ts=4 sw=4 tw=99 noet :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod SQLite Extension
|
* SourceMod SQLite Extension
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@ -66,24 +66,16 @@ int busy_handler(void *unused1, int unused2)
|
|||||||
SqDriver::SqDriver()
|
SqDriver::SqDriver()
|
||||||
{
|
{
|
||||||
m_Handle = BAD_HANDLE;
|
m_Handle = BAD_HANDLE;
|
||||||
m_pOpenLock = NULL;
|
|
||||||
m_bThreadSafe = false;
|
m_bThreadSafe = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SqDriver::Initialize()
|
void SqDriver::Initialize()
|
||||||
{
|
{
|
||||||
m_pOpenLock = threader->MakeMutex();
|
|
||||||
|
|
||||||
InitializeThreadSafety();
|
InitializeThreadSafety();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SqDriver::Shutdown()
|
void SqDriver::Shutdown()
|
||||||
{
|
{
|
||||||
if (m_pOpenLock)
|
|
||||||
{
|
|
||||||
m_pOpenLock->DestroyThis();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_bThreadSafe)
|
if (m_bThreadSafe)
|
||||||
{
|
{
|
||||||
sqlite3_enable_shared_cache(0);
|
sqlite3_enable_shared_cache(0);
|
||||||
@ -158,8 +150,7 @@ inline bool IsPathSepChar(char c)
|
|||||||
|
|
||||||
IDatabase *SqDriver::Connect(const DatabaseInfo *info, bool persistent, char *error, size_t maxlength)
|
IDatabase *SqDriver::Connect(const DatabaseInfo *info, bool persistent, char *error, size_t maxlength)
|
||||||
{
|
{
|
||||||
/* We wrap most of the open process in a mutex just to be safe */
|
ke::AutoLock lock(&m_OpenLock);
|
||||||
m_pOpenLock->Lock();
|
|
||||||
|
|
||||||
/* Format our path */
|
/* Format our path */
|
||||||
char path[PLATFORM_MAX_PATH];
|
char path[PLATFORM_MAX_PATH];
|
||||||
@ -189,7 +180,6 @@ IDatabase *SqDriver::Connect(const DatabaseInfo *info, bool persistent, char *er
|
|||||||
if (!libsys->CreateFolder(fullpath))
|
if (!libsys->CreateFolder(fullpath))
|
||||||
{
|
{
|
||||||
strncopy(error, "Could not create or open \"data\" folder\"", maxlength);
|
strncopy(error, "Could not create or open \"data\" folder\"", maxlength);
|
||||||
m_pOpenLock->Unlock();
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -237,7 +227,6 @@ IDatabase *SqDriver::Connect(const DatabaseInfo *info, bool persistent, char *er
|
|||||||
if ((*iter).path.compare(fullpath) == 0)
|
if ((*iter).path.compare(fullpath) == 0)
|
||||||
{
|
{
|
||||||
(*iter).db->IncReferenceCount();
|
(*iter).db->IncReferenceCount();
|
||||||
m_pOpenLock->Unlock();
|
|
||||||
return (*iter).db;
|
return (*iter).db;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -250,7 +239,6 @@ IDatabase *SqDriver::Connect(const DatabaseInfo *info, bool persistent, char *er
|
|||||||
{
|
{
|
||||||
strncopy(error, sqlite3_errmsg(sql), maxlength);
|
strncopy(error, sqlite3_errmsg(sql), maxlength);
|
||||||
sqlite3_close(sql);
|
sqlite3_close(sql);
|
||||||
m_pOpenLock->Unlock();
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,13 +254,13 @@ IDatabase *SqDriver::Connect(const DatabaseInfo *info, bool persistent, char *er
|
|||||||
m_Cache.push_back(pinfo);
|
m_Cache.push_back(pinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pOpenLock->Unlock();
|
|
||||||
|
|
||||||
return pdb;
|
return pdb;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SqDriver::RemovePersistent(IDatabase *pdb)
|
void SqDriver::RemovePersistent(IDatabase *pdb)
|
||||||
{
|
{
|
||||||
|
ke::AutoLock lock(&m_OpenLock);
|
||||||
|
|
||||||
List<SqDbInfo>::iterator iter;
|
List<SqDbInfo>::iterator iter;
|
||||||
for (iter = m_Cache.begin(); iter != m_Cache.end(); iter++)
|
for (iter = m_Cache.begin(); iter != m_Cache.end(); iter++)
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 :
|
* vim: set ts=4 sw=4 tw=99 noet :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod SQLite Extension
|
* SourceMod SQLite Extension
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@ -32,10 +32,11 @@
|
|||||||
#ifndef _INCLUDE_SQLITE_SOURCEMOD_DRIVER_H_
|
#ifndef _INCLUDE_SQLITE_SOURCEMOD_DRIVER_H_
|
||||||
#define _INCLUDE_SQLITE_SOURCEMOD_DRIVER_H_
|
#define _INCLUDE_SQLITE_SOURCEMOD_DRIVER_H_
|
||||||
|
|
||||||
|
#define SOURCEMOD_SQL_DRIVER_CODE
|
||||||
#include <IDBDriver.h>
|
#include <IDBDriver.h>
|
||||||
#include <IThreader.h>
|
|
||||||
#include <sh_list.h>
|
#include <sh_list.h>
|
||||||
#include <sh_string.h>
|
#include <sh_string.h>
|
||||||
|
#include <am-thread-utils.h>
|
||||||
#include "sqlite-source/sqlite3.h"
|
#include "sqlite-source/sqlite3.h"
|
||||||
|
|
||||||
using namespace SourceMod;
|
using namespace SourceMod;
|
||||||
@ -70,7 +71,7 @@ public:
|
|||||||
void RemovePersistent(IDatabase *pdb);
|
void RemovePersistent(IDatabase *pdb);
|
||||||
private:
|
private:
|
||||||
Handle_t m_Handle;
|
Handle_t m_Handle;
|
||||||
IMutex *m_pOpenLock;
|
ke::Mutex m_OpenLock;
|
||||||
List<SqDbInfo> m_Cache;
|
List<SqDbInfo> m_Cache;
|
||||||
bool m_bThreadSafe;
|
bool m_bThreadSafe;
|
||||||
};
|
};
|
||||||
|
@ -36,14 +36,12 @@ SqQuery::SqQuery(SqDatabase *parent, sqlite3_stmt *stmt) :
|
|||||||
{
|
{
|
||||||
m_ParamCount = sqlite3_bind_parameter_count(m_pStmt);
|
m_ParamCount = sqlite3_bind_parameter_count(m_pStmt);
|
||||||
m_ColCount = sqlite3_column_count(m_pStmt);
|
m_ColCount = sqlite3_column_count(m_pStmt);
|
||||||
m_pParent->IncReferenceCount();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SqQuery::~SqQuery()
|
SqQuery::~SqQuery()
|
||||||
{
|
{
|
||||||
delete m_pResults;
|
delete m_pResults;
|
||||||
sqlite3_finalize(m_pStmt);
|
sqlite3_finalize(m_pStmt);
|
||||||
m_pParent->Close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IResultSet *SqQuery::GetResultSet()
|
IResultSet *SqQuery::GetResultSet()
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 :
|
* vim: set ts=4 sw=4 tw=99 noet :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod SQLite Extension
|
* SourceMod SQLite Extension
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@ -32,6 +32,7 @@
|
|||||||
#ifndef _INCLUDE_SQLITE_SOURCEMOD_QUERY_H_
|
#ifndef _INCLUDE_SQLITE_SOURCEMOD_QUERY_H_
|
||||||
#define _INCLUDE_SQLITE_SOURCEMOD_QUERY_H_
|
#define _INCLUDE_SQLITE_SOURCEMOD_QUERY_H_
|
||||||
|
|
||||||
|
#include <am-refcounting.h>
|
||||||
#include "SqDatabase.h"
|
#include "SqDatabase.h"
|
||||||
#include "SqResults.h"
|
#include "SqResults.h"
|
||||||
|
|
||||||
@ -81,7 +82,7 @@ public: //IResultRow
|
|||||||
public:
|
public:
|
||||||
sqlite3_stmt *GetStmt();
|
sqlite3_stmt *GetStmt();
|
||||||
private:
|
private:
|
||||||
SqDatabase *m_pParent;
|
ke::Ref<SqDatabase> m_pParent;
|
||||||
sqlite3_stmt *m_pStmt;
|
sqlite3_stmt *m_pStmt;
|
||||||
SqResults *m_pResults;
|
SqResults *m_pResults;
|
||||||
unsigned int m_ParamCount;
|
unsigned int m_ParamCount;
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
* @brief Sample extension code header.
|
* @brief Sample extension code header.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define SOURCEMOD_SQL_DRIVER_CODE
|
||||||
#include "smsdk_ext.h"
|
#include "smsdk_ext.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@
|
|||||||
//#define SMEXT_ENABLE_MEMUTILS
|
//#define SMEXT_ENABLE_MEMUTILS
|
||||||
//#define SMEXT_ENABLE_GAMEHELPERS
|
//#define SMEXT_ENABLE_GAMEHELPERS
|
||||||
//#define SMEXT_ENABLE_TIMERSYS
|
//#define SMEXT_ENABLE_TIMERSYS
|
||||||
#define SMEXT_ENABLE_THREADER
|
//#define SMEXT_ENABLE_THREADER
|
||||||
#define SMEXT_ENABLE_LIBSYS
|
#define SMEXT_ENABLE_LIBSYS
|
||||||
|
|
||||||
#endif // _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
|
#endif // _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
|
||||||
|
@ -608,6 +608,7 @@ namespace SourceMod
|
|||||||
*/
|
*/
|
||||||
virtual bool SetCharacterSet(const char *characterset) =0;
|
virtual bool SetCharacterSet(const char *characterset) =0;
|
||||||
|
|
||||||
|
#if !defined(SOURCEMOD_SQL_DRIVER_CODE)
|
||||||
/**
|
/**
|
||||||
* @brief Wrapper around IncReferenceCount(), for ke::Ref.
|
* @brief Wrapper around IncReferenceCount(), for ke::Ref.
|
||||||
*/
|
*/
|
||||||
@ -621,6 +622,7 @@ namespace SourceMod
|
|||||||
void Release() {
|
void Release() {
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
100
public/amtl/am-atomics.h
Normal file
100
public/amtl/am-atomics.h
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
// vim: set sts=8 ts=2 sw=2 tw=99 et:
|
||||||
|
//
|
||||||
|
// Copyright (C) 2013, David Anderson and AlliedModders LLC
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright notice, this
|
||||||
|
// list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer in the documentation
|
||||||
|
// and/or other materials provided with the distribution.
|
||||||
|
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
||||||
|
// may be used to endorse or promote products derived from this software
|
||||||
|
// without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#ifndef _include_amtl_atomics_h_
|
||||||
|
#define _include_amtl_atomics_h_
|
||||||
|
|
||||||
|
#include <am-utility.h>
|
||||||
|
|
||||||
|
namespace ke {
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
extern "C" {
|
||||||
|
long __cdecl _InterlockedIncrement(long volatile *dest);
|
||||||
|
long __cdecl _InterlockedDecrement(long volatile *dest);
|
||||||
|
}
|
||||||
|
# pragma intrinsic(_InterlockedIncrement);
|
||||||
|
# pragma intrinsic(_InterlockedDecrement);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <size_t Width>
|
||||||
|
struct AtomicOps;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct AtomicOps<4>
|
||||||
|
{
|
||||||
|
typedef int Type;
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
static int Increment(int *ptr) {
|
||||||
|
return _InterlockedIncrement(ptr);
|
||||||
|
}
|
||||||
|
static int Decrement(int *ptr) {
|
||||||
|
return _InterlockedDecrement(ptr);
|
||||||
|
};
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
// x86/x64 notes: When using GCC < 4.8, this will compile to a spinlock.
|
||||||
|
// On 4.8+, or when using Clang, we'll get the more optimal "lock addl"
|
||||||
|
// variant.
|
||||||
|
static int Increment(int *ptr) {
|
||||||
|
return __sync_add_and_fetch(ptr, 1);
|
||||||
|
}
|
||||||
|
static int Decrement(int *ptr) {
|
||||||
|
return __sync_sub_and_fetch(ptr, 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
class AtomicRefCount
|
||||||
|
{
|
||||||
|
typedef AtomicOps<sizeof(uintptr_t)> Ops;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AtomicRefCount(uintptr_t value)
|
||||||
|
: value_(value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void increment() {
|
||||||
|
Ops::Increment(&value_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return false if all references are gone.
|
||||||
|
bool decrement() {
|
||||||
|
return Ops::Decrement(&value_) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ops::Type value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _include_amtl_atomics_h_
|
||||||
|
|
68
public/amtl/am-refcounting-threadsafe.h
Normal file
68
public/amtl/am-refcounting-threadsafe.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
// vim: set sts=8 ts=2 sw=2 tw=99 et:
|
||||||
|
//
|
||||||
|
// Copyright (C) 2013, David Anderson and AlliedModders LLC
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright notice, this
|
||||||
|
// list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer in the documentation
|
||||||
|
// and/or other materials provided with the distribution.
|
||||||
|
// * Neither the name of AlliedModders LLC nor the names of its contributors
|
||||||
|
// may be used to endorse or promote products derived from this software
|
||||||
|
// without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#ifndef _include_amtl_ts_refcounting_h_
|
||||||
|
#define _include_amtl_ts_refcounting_h_
|
||||||
|
|
||||||
|
#include <am-refcounting.h>
|
||||||
|
#include <am-atomics.h>
|
||||||
|
|
||||||
|
namespace ke {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class RefcountedThreadsafe
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RefcountedThreadsafe()
|
||||||
|
: refcount_(1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddRef() {
|
||||||
|
refcount_.increment();
|
||||||
|
}
|
||||||
|
bool Release() {
|
||||||
|
if (!refcount_.decrement()) {
|
||||||
|
delete static_cast<T *>(this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
~RefcountedThreadsafe() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
AtomicRefCount refcount_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ke
|
||||||
|
|
||||||
|
#endif // _include_amtl_ts_refcounting_h_
|
Loading…
Reference in New Issue
Block a user