new dbi API additions to support threading

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401101
This commit is contained in:
David Anderson 2007-07-13 19:19:30 +00:00
parent 41aa77314d
commit 93c9ffdf02
12 changed files with 202 additions and 20 deletions

View File

@ -39,10 +39,14 @@ bool DBI_MySQL::SDK_OnLoad(char *error, size_t maxlength, bool late)
{ {
dbi->AddDriver(&g_MyDriver); dbi->AddDriver(&g_MyDriver);
my_init();
return true; return true;
} }
void DBI_MySQL::SDK_OnUnload() void DBI_MySQL::SDK_OnUnload()
{ {
dbi->RemoveDriver(&g_MyDriver); dbi->RemoveDriver(&g_MyDriver);
//:TODO: is this needed?
//mysql_library_end();
} }

View File

@ -214,6 +214,10 @@
Name="SourceMod SDK" Name="SourceMod SDK"
UniqueIdentifier="{31958233-BB2D-4e41-A8F9-CE8A4684F436}" UniqueIdentifier="{31958233-BB2D-4e41-A8F9-CE8A4684F436}"
> >
<File
RelativePath="..\..\..\public\IDBDriver.h"
>
</File>
<File <File
RelativePath="..\sdk\smsdk_config.h" RelativePath="..\sdk\smsdk_config.h"
> >

View File

@ -276,7 +276,7 @@ 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->IncRefCount(); m_pParent->IncReferenceCount();
} }
IResultSet *MyQuery::GetResultSet() IResultSet *MyQuery::GetResultSet()

View File

@ -56,7 +56,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_bPersistent(persistent) : m_mysql(mysql), m_refcount(1), m_pFullLock(NULL), m_bPersistent(persistent)
{ {
m_Host.assign(info->host); m_Host.assign(info->host);
m_Database.assign(info->database); m_Database.assign(info->database);
@ -78,7 +78,7 @@ MyDatabase::~MyDatabase()
m_mysql = NULL; m_mysql = NULL;
} }
void MyDatabase::IncRefCount() void MyDatabase::IncReferenceCount()
{ {
m_refcount++; m_refcount++;
} }
@ -212,3 +212,32 @@ IPreparedQuery *MyDatabase::PrepareQuery(const char *query, char *error, size_t
return new MyStatement(this, stmt); return new MyStatement(this, stmt);
} }
bool MyDatabase::LockForFullAtomicOperation()
{
if (!m_pFullLock)
{
m_pFullLock = threader->MakeMutex();
if (!m_pFullLock)
{
return false;
}
}
m_pFullLock->Lock();
return true;
}
void MyDatabase::UnlockFromFullAtomicOperation()
{
if (m_pFullLock)
{
m_pFullLock->Unlock();
}
}
IDBDriver *MyDatabase::GetDriver()
{
return &g_MyDriver;
}

View File

@ -2,6 +2,7 @@
#define _INCLUDE_SM_MYSQL_DATABASE_H_ #define _INCLUDE_SM_MYSQL_DATABASE_H_
#include "MyDriver.h" #include "MyDriver.h"
#include <IThreader.h>
class MyQuery; class MyQuery;
class MyStatement; class MyStatement;
@ -22,12 +23,16 @@ public: //IDatabase
bool QuoteString(const char *str, char buffer[], size_t maxlen, size_t *newSize); bool QuoteString(const char *str, char buffer[], size_t maxlen, size_t *newSize);
unsigned int GetAffectedRows(); unsigned int GetAffectedRows();
unsigned int GetInsertID(); unsigned int GetInsertID();
bool LockForFullAtomicOperation();
void UnlockFromFullAtomicOperation();
void IncReferenceCount();
IDBDriver *GetDriver();
public: public:
const DatabaseInfo &GetInfo(); const DatabaseInfo &GetInfo();
void IncRefCount();
private: private:
MYSQL *m_mysql; MYSQL *m_mysql;
unsigned int m_refcount; unsigned int m_refcount;
IMutex *m_pFullLock;
/* ---------- */ /* ---------- */
DatabaseInfo m_Info; DatabaseInfo m_Info;

View File

@ -121,7 +121,7 @@ IDatabase *MyDriver::Connect(const DatabaseInfo *info, bool persistent, char *er
&& CompareField(info->database, other.database) && CompareField(info->database, other.database)
&& (info->port == other.port)) && (info->port == other.port))
{ {
db->IncRefCount(); db->IncReferenceCount();
return db; return db;
} }
} }
@ -151,6 +151,21 @@ void MyDriver::RemoveFromList(MyDatabase *pdb, bool persistent)
} }
} }
bool MyDriver::IsThreadSafe()
{
return (mysql_thread_safe() != 0);
}
bool MyDriver::InitializeThreadSafety()
{
return (mysql_thread_init() == 0);
}
void MyDriver::ShutdownThreadSafety()
{
mysql_thread_end();
}
unsigned int strncopy(char *dest, const char *src, size_t count) unsigned int strncopy(char *dest, const char *src, size_t count)
{ {
if (!count) if (!count)

View File

@ -29,6 +29,9 @@ public: //IDBDriver
const char *GetProductName(); const char *GetProductName();
Handle_t GetHandle(); Handle_t GetHandle();
IdentityToken_t *GetIdentity(); IdentityToken_t *GetIdentity();
bool IsThreadSafe();
bool InitializeThreadSafety();
void ShutdownThreadSafety();
public: public:
void Shutdown(); void Shutdown();
void RemoveFromList(MyDatabase *pdb, bool persistent); void RemoveFromList(MyDatabase *pdb, bool persistent);

View File

@ -17,7 +17,7 @@ MyStatement::MyStatement(MyDatabase *db, MYSQL_STMT *stmt)
m_bind = NULL; m_bind = NULL;
} }
m_pParent->IncRefCount(); m_pParent->IncReferenceCount();
m_pRes = mysql_stmt_result_metadata(stmt); m_pRes = mysql_stmt_result_metadata(stmt);
m_Results = false; m_Results = false;

View File

@ -52,5 +52,10 @@
//#define SMEXT_ENABLE_HANDLESYS //#define SMEXT_ENABLE_HANDLESYS
//#define SMEXT_ENABLE_PLAYERHELPERS //#define SMEXT_ENABLE_PLAYERHELPERS
#define SMEXT_ENABLE_DBMANAGER #define SMEXT_ENABLE_DBMANAGER
//#define SMEXT_ENABLE_GAMECONF
//#define SMEXT_ENABLE_MEMUTILS
//#define SMEXT_ENABLE_GAMEHELPERS
//#define SMEXT_ENABLE_TIMERSYS
#define SMEXT_ENABLE_THREADER
#endif // _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_ #endif // _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_

View File

@ -13,7 +13,7 @@
* *
* To view the latest information, see: http://www.sourcemod.net/license.php * To view the latest information, see: http://www.sourcemod.net/license.php
* *
* Version: $Id: smsdk_ext.cpp 763 2007-05-09 05:20:03Z damagedsoul $ * Version: $Id: smsdk_ext.cpp 1034 2007-06-30 16:43:11Z dvander $
*/ */
#include <stdio.h> #include <stdio.h>
@ -40,11 +40,29 @@ IHandleSys *g_pHandleSys = NULL; /**< Handle system */
IHandleSys *handlesys = NULL; /**< Handle system */ IHandleSys *handlesys = NULL; /**< Handle system */
#endif #endif
#if defined SMEXT_ENABLE_PLAYERHELPERS #if defined SMEXT_ENABLE_PLAYERHELPERS
IPlayerHelpers *playerhelpers = NULL; /**< Player helpers */ IPlayerManager *playerhelpers = NULL; /**< Player helpers */
#endif //SMEXT_ENABLE_PLAYERHELPERS #endif //SMEXT_ENABLE_PLAYERHELPERS
#if defined SMEXT_ENABLE_DBMANAGER #if defined SMEXT_ENABLE_DBMANAGER
IDBManager *dbi = NULL; /**< DB Manager */ IDBManager *dbi = NULL; /**< DB Manager */
#endif //SMEXT_ENABLE_DBMANAGER #endif //SMEXT_ENABLE_DBMANAGER
#if defined SMEXT_ENABLE_GAMECONF
IGameConfigManager *gameconfs = NULL; /**< Game config manager */
#endif //SMEXT_ENABLE_DBMANAGER
#if defined SMEXT_ENABLE_MEMUTILS
IMemoryUtils *memutils = NULL;
#endif //SMEXT_ENABLE_DBMANAGER
#if defined SMEXT_ENABLE_GAMEHELPERS
IGameHelpers *gamehelpers = NULL;
#endif
#if defined SMEXT_ENABLE_TIMERSYS
ITimerSystem *timersys = NULL;
#endif
#if defined SMEXT_ENABLE_ADTFACTORY
IADTFactory *adtfactory = NULL;
#endif
#if defined SMEXT_ENABLE_THREADER
IThreader *threader = NULL;
#endif
/** Exports the main interface */ /** Exports the main interface */
PLATFORM_EXTERN_C IExtensionInterface *GetSMExtAPI() PLATFORM_EXTERN_C IExtensionInterface *GetSMExtAPI()
@ -94,6 +112,24 @@ bool SDKExtension::OnExtensionLoad(IExtension *me, IShareSys *sys, char *error,
#if defined SMEXT_ENABLE_DBMANAGER #if defined SMEXT_ENABLE_DBMANAGER
SM_GET_IFACE(DBI, dbi); SM_GET_IFACE(DBI, dbi);
#endif #endif
#if defined SMEXT_ENABLE_GAMECONF
SM_GET_IFACE(GAMECONFIG, gameconfs);
#endif
#if defined SMEXT_ENABLE_MEMUTILS
SM_GET_IFACE(MEMORYUTILS, memutils);
#endif
#if defined SMEXT_ENABLE_GAMEHELPERS
SM_GET_IFACE(GAMEHELPERS, gamehelpers);
#endif
#if defined SMEXT_ENABLE_TIMERSYS
SM_GET_IFACE(TIMERSYS, timersys);
#endif
#if defined SMEXT_ENABLE_ADTFACTORY
SM_GET_IFACE(ADTFACTORY, adtfactory);
#endif
#if defined SMEXT_ENABLE_THREADER
SM_GET_IFACE(THREADER, threader);
#endif
if (SDK_OnLoad(error, maxlength, late)) if (SDK_OnLoad(error, maxlength, late))
{ {

View File

@ -13,7 +13,7 @@
* *
* To view the latest information, see: http://www.sourcemod.net/license.php * To view the latest information, see: http://www.sourcemod.net/license.php
* *
* Version: $Id: smsdk_ext.h 763 2007-05-09 05:20:03Z damagedsoul $ * Version: $Id: smsdk_ext.h 1034 2007-06-30 16:43:11Z dvander $
*/ */
#ifndef _INCLUDE_SOURCEMOD_EXTENSION_BASESDK_H_ #ifndef _INCLUDE_SOURCEMOD_EXTENSION_BASESDK_H_
@ -39,6 +39,24 @@
#if defined SMEXT_ENABLE_DBMANAGER #if defined SMEXT_ENABLE_DBMANAGER
#include <IDBDriver.h> #include <IDBDriver.h>
#endif //SMEXT_ENABLE_DBMANAGER #endif //SMEXT_ENABLE_DBMANAGER
#if defined SMEXT_ENABLE_GAMECONF
#include <IGameConfigs.h>
#endif
#if defined SMEXT_ENABLE_MEMUTILS
#include <IMemoryUtils.h>
#endif
#if defined SMEXT_ENABLE_GAMEHELPERS
#include <IGameHelpers.h>
#endif
#if defined SMEXT_ENABLE_TIMERSYS
#include <ITimerSystem.h>
#endif
#if defined SMEXT_ENABLE_ADTFACTORY
#include <IADTFactory.h>
#endif
#if defined SMEXT_ENABLE_THREADER
#include <IThreader.h>
#endif
#if defined SMEXT_CONF_METAMOD #if defined SMEXT_CONF_METAMOD
#include <ISmmPlugin.h> #include <ISmmPlugin.h>
@ -196,11 +214,29 @@ extern IHandleSys *g_pHandleSys;
extern IHandleSys *handlesys; /* Note: Newer name */ extern IHandleSys *handlesys; /* Note: Newer name */
#endif //SMEXT_ENABLE_HANDLESYS #endif //SMEXT_ENABLE_HANDLESYS
#if defined SMEXT_ENABLE_PLAYERHELPERS #if defined SMEXT_ENABLE_PLAYERHELPERS
extern IPlayerHelpers *playerhelpers; extern IPlayerManager *playerhelpers;
#endif //SMEXT_ENABLE_PLAYERHELPERS #endif //SMEXT_ENABLE_PLAYERHELPERS
#if defined SMEXT_ENABLE_DBMANAGER #if defined SMEXT_ENABLE_DBMANAGER
extern IDBManager *dbi; extern IDBManager *dbi;
#endif //SMEXT_ENABLE_DBMANAGER #endif //SMEXT_ENABLE_DBMANAGER
#if defined SMEXT_ENABLE_GAMECONF
extern IGameConfigManager *gameconfs;
#endif //SMEXT_ENABLE_DBMANAGER
#if defined SMEXT_ENABLE_MEMUTILS
extern IMemoryUtils *memutils;
#endif
#if defined SMEXT_ENABLE_GAMEHELPERS
extern IGameHelpers *gamehelpers;
#endif
#if defined SMEXT_ENABLE_TIMERSYS
extern ITimerSystem *timersys;
#endif
#if defined SMEXT_ENABLE_ADTFACTORY
extern IADTFactory *adtfactory;
#endif
#if defined SMEXT_ENABLE_THREADER
extern IThreader *threader;
#endif
#if defined SMEXT_CONF_METAMOD #if defined SMEXT_CONF_METAMOD
PLUGIN_GLOBALVARS(); PLUGIN_GLOBALVARS();

View File

@ -24,7 +24,7 @@
#include <string.h> #include <string.h>
#define SMINTERFACE_DBI_NAME "IDBI" #define SMINTERFACE_DBI_NAME "IDBI"
#define SMINTERFACE_DBI_VERSION 3 #define SMINTERFACE_DBI_VERSION 4
namespace SourceMod namespace SourceMod
{ {
@ -396,6 +396,8 @@ namespace SourceMod
virtual unsigned int GetInsertID() =0; virtual unsigned int GetInsertID() =0;
}; };
class IDBDriver;
/** /**
* @brief Encapsulates a database connection. * @brief Encapsulates a database connection.
*/ */
@ -484,6 +486,28 @@ namespace SourceMod
* @return Row insertion ID of the last execute, if any. * @return Row insertion ID of the last execute, if any.
*/ */
virtual unsigned int GetInsertID() =0; virtual unsigned int GetInsertID() =0;
/**
* @brief Locks the database for an atomic query+retrieval operation.
*
* @return True on success, false if not supported.
*/
virtual bool LockForFullAtomicOperation() =0;
/**
* @brief Unlocks a locked atomic fetch.
*/
virtual void UnlockFromFullAtomicOperation() =0;
/**
* @brief Increases the reference count on the database.
*/
virtual void IncReferenceCount() =0;
/**
* @brief Returns the parent driver.
*/
virtual IDBDriver *GetDriver() =0;
}; };
/** /**
@ -558,6 +582,25 @@ namespace SourceMod
* @return An IdentityToken_t identity. * @return An IdentityToken_t identity.
*/ */
virtual IdentityToken_t *GetIdentity() =0; virtual IdentityToken_t *GetIdentity() =0;
/**
* @brief Returns whether the driver is thread safe.
*
* @return True if thread safe, false otherwise.
*/
virtual bool IsThreadSafe() =0;
/**
* @brief Initializes thread safety for the calling thread.
*
* @return True on success, false otherwise.
*/
virtual bool InitializeThreadSafety() =0;
/**
* @brief Shuts down thread safety for the calling thread.
*/
virtual void ShutdownThreadSafety() =0;
}; };
/** /**
@ -579,14 +622,14 @@ namespace SourceMod
virtual unsigned int GetInterfaceVersion() =0; virtual unsigned int GetInterfaceVersion() =0;
public: public:
/** /**
* @brief Adds a driver to the DBI system. * @brief Adds a driver to the DBI system. Not thread safe.
* *
* @param pDriver Database driver. * @param pDriver Database driver.
*/ */
virtual void AddDriver(IDBDriver *pDriver) =0; virtual void AddDriver(IDBDriver *pDriver) =0;
/** /**
* @brief Removes a driver from the DBI system. * @brief Removes a driver from the DBI system. Not thread safe.
* *
* @param pDriver Database driver. * @param pDriver Database driver.
*/ */
@ -602,7 +645,7 @@ namespace SourceMod
virtual const DatabaseInfo *FindDatabaseConf(const char *name) =0; virtual const DatabaseInfo *FindDatabaseConf(const char *name) =0;
/** /**
* @brief Tries to connect to a named database. * @brief Tries to connect to a named database. Not thread safe.
* *
* @param name Named database info. * @param name Named database info.
* @param pdr Pointer to store the IDBDriver pointer in. * @param pdr Pointer to store the IDBDriver pointer in.
@ -623,14 +666,14 @@ namespace SourceMod
size_t maxlength) =0; size_t maxlength) =0;
/** /**
* @brief Returns the number of drivers loaded. * @brief Returns the number of drivers loaded. Not thread safe.
* *
* @return Number of drivers loaded. * @return Number of drivers loaded.
*/ */
virtual unsigned int GetDriverCount() =0; virtual unsigned int GetDriverCount() =0;
/** /**
* @brief Returns a driver by index. * @brief Returns a driver by index. Not thread safe.
* *
* @param index Driver index, starting from 0. * @param index Driver index, starting from 0.
* @return IDBDriver pointer for the given index. * @return IDBDriver pointer for the given index.
@ -638,7 +681,7 @@ namespace SourceMod
virtual IDBDriver *GetDriver(unsigned int index) =0; virtual IDBDriver *GetDriver(unsigned int index) =0;
/** /**
* @brief Creates a Handle_t of the IDBDriver type. * @brief Creates a Handle_t of the IDBDriver type. Not thread safe.
* *
* @param type A DBHandleType value. * @param type A DBHandleType value.
* @param ptr A pointer corrresponding to a DBHandleType * @param ptr A pointer corrresponding to a DBHandleType
@ -649,7 +692,8 @@ namespace SourceMod
virtual Handle_t CreateHandle(DBHandleType type, void *ptr, IdentityToken_t *pToken) =0; virtual Handle_t CreateHandle(DBHandleType type, void *ptr, IdentityToken_t *pToken) =0;
/** /**
* @brief Reads an IDBDriver pointer from an IDBDriver handle. * @brief Reads an IDBDriver pointer from an IDBDriver handle. Not
* thread safe.
* *
* @param hndl Handle_t handle to read. * @param hndl Handle_t handle to read.
* @param type A DBHandleType value. * @param type A DBHandleType value.
@ -670,7 +714,7 @@ namespace SourceMod
/** /**
* @brief Given a driver name, attempts to find it. If it is not found, SourceMod * @brief Given a driver name, attempts to find it. If it is not found, SourceMod
* will attempt to load it. * will attempt to load it. This function is not thread safe.
* *
* @param name Driver identifier name. * @param name Driver identifier name.
* @return IDBDriver pointer on success, NULL otherwise. * @return IDBDriver pointer on success, NULL otherwise.
@ -678,7 +722,8 @@ namespace SourceMod
virtual IDBDriver *FindOrLoadDriver(const char *driver) =0; virtual IDBDriver *FindOrLoadDriver(const char *driver) =0;
/** /**
* @brief Returns the default driver, or NULL if none is set. * @brief Returns the default driver, or NULL if none is set. This
* function is not thread safe.
* *
* @return IDBDriver pointer on success, NULL otherwise. * @return IDBDriver pointer on success, NULL otherwise.
*/ */