diff --git a/extensions/mysql/extension.cpp b/extensions/mysql/extension.cpp index fe0de158..2f49c295 100644 --- a/extensions/mysql/extension.cpp +++ b/extensions/mysql/extension.cpp @@ -39,10 +39,14 @@ bool DBI_MySQL::SDK_OnLoad(char *error, size_t maxlength, bool late) { dbi->AddDriver(&g_MyDriver); + my_init(); + return true; } void DBI_MySQL::SDK_OnUnload() { dbi->RemoveDriver(&g_MyDriver); + //:TODO: is this needed? + //mysql_library_end(); } diff --git a/extensions/mysql/msvc8/sm_mysql.vcproj b/extensions/mysql/msvc8/sm_mysql.vcproj index bad6befa..40bd6d3b 100644 --- a/extensions/mysql/msvc8/sm_mysql.vcproj +++ b/extensions/mysql/msvc8/sm_mysql.vcproj @@ -214,6 +214,10 @@ Name="SourceMod SDK" UniqueIdentifier="{31958233-BB2D-4e41-A8F9-CE8A4684F436}" > + + diff --git a/extensions/mysql/mysql/MyBasicResults.cpp b/extensions/mysql/mysql/MyBasicResults.cpp index 96d75c5e..4c059375 100644 --- a/extensions/mysql/mysql/MyBasicResults.cpp +++ b/extensions/mysql/mysql/MyBasicResults.cpp @@ -276,7 +276,7 @@ DBResult MyBasicResults::CopyBlob(unsigned int columnId, void *buffer, size_t ma MyQuery::MyQuery(MyDatabase *db, MYSQL_RES *res) : m_pParent(db), m_rs(res) { - m_pParent->IncRefCount(); + m_pParent->IncReferenceCount(); } IResultSet *MyQuery::GetResultSet() diff --git a/extensions/mysql/mysql/MyDatabase.cpp b/extensions/mysql/mysql/MyDatabase.cpp index e5791acf..bf75c3bf 100644 --- a/extensions/mysql/mysql/MyDatabase.cpp +++ b/extensions/mysql/mysql/MyDatabase.cpp @@ -56,7 +56,7 @@ DBType GetOurType(enum_field_types type) } 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_Database.assign(info->database); @@ -78,7 +78,7 @@ MyDatabase::~MyDatabase() m_mysql = NULL; } -void MyDatabase::IncRefCount() +void MyDatabase::IncReferenceCount() { m_refcount++; } @@ -212,3 +212,32 @@ IPreparedQuery *MyDatabase::PrepareQuery(const char *query, char *error, size_t 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; +} diff --git a/extensions/mysql/mysql/MyDatabase.h b/extensions/mysql/mysql/MyDatabase.h index eedaffc8..b346205f 100644 --- a/extensions/mysql/mysql/MyDatabase.h +++ b/extensions/mysql/mysql/MyDatabase.h @@ -2,6 +2,7 @@ #define _INCLUDE_SM_MYSQL_DATABASE_H_ #include "MyDriver.h" +#include class MyQuery; class MyStatement; @@ -22,12 +23,16 @@ public: //IDatabase bool QuoteString(const char *str, char buffer[], size_t maxlen, size_t *newSize); unsigned int GetAffectedRows(); unsigned int GetInsertID(); + bool LockForFullAtomicOperation(); + void UnlockFromFullAtomicOperation(); + void IncReferenceCount(); + IDBDriver *GetDriver(); public: const DatabaseInfo &GetInfo(); - void IncRefCount(); private: MYSQL *m_mysql; unsigned int m_refcount; + IMutex *m_pFullLock; /* ---------- */ DatabaseInfo m_Info; diff --git a/extensions/mysql/mysql/MyDriver.cpp b/extensions/mysql/mysql/MyDriver.cpp index e52173ba..be2694de 100644 --- a/extensions/mysql/mysql/MyDriver.cpp +++ b/extensions/mysql/mysql/MyDriver.cpp @@ -121,7 +121,7 @@ IDatabase *MyDriver::Connect(const DatabaseInfo *info, bool persistent, char *er && CompareField(info->database, other.database) && (info->port == other.port)) { - db->IncRefCount(); + db->IncReferenceCount(); 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) { if (!count) diff --git a/extensions/mysql/mysql/MyDriver.h b/extensions/mysql/mysql/MyDriver.h index 6a41cf24..9186d2e4 100644 --- a/extensions/mysql/mysql/MyDriver.h +++ b/extensions/mysql/mysql/MyDriver.h @@ -29,6 +29,9 @@ public: //IDBDriver const char *GetProductName(); Handle_t GetHandle(); IdentityToken_t *GetIdentity(); + bool IsThreadSafe(); + bool InitializeThreadSafety(); + void ShutdownThreadSafety(); public: void Shutdown(); void RemoveFromList(MyDatabase *pdb, bool persistent); diff --git a/extensions/mysql/mysql/MyStatement.cpp b/extensions/mysql/mysql/MyStatement.cpp index b1038abd..ee81ad27 100644 --- a/extensions/mysql/mysql/MyStatement.cpp +++ b/extensions/mysql/mysql/MyStatement.cpp @@ -17,7 +17,7 @@ MyStatement::MyStatement(MyDatabase *db, MYSQL_STMT *stmt) m_bind = NULL; } - m_pParent->IncRefCount(); + m_pParent->IncReferenceCount(); m_pRes = mysql_stmt_result_metadata(stmt); m_Results = false; diff --git a/extensions/mysql/sdk/smsdk_config.h b/extensions/mysql/sdk/smsdk_config.h index d5d10110..e724188a 100644 --- a/extensions/mysql/sdk/smsdk_config.h +++ b/extensions/mysql/sdk/smsdk_config.h @@ -52,5 +52,10 @@ //#define SMEXT_ENABLE_HANDLESYS //#define SMEXT_ENABLE_PLAYERHELPERS #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_ diff --git a/extensions/mysql/sdk/smsdk_ext.cpp b/extensions/mysql/sdk/smsdk_ext.cpp index 9d6c8cca..99c4674e 100644 --- a/extensions/mysql/sdk/smsdk_ext.cpp +++ b/extensions/mysql/sdk/smsdk_ext.cpp @@ -13,7 +13,7 @@ * * 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 @@ -40,11 +40,29 @@ IHandleSys *g_pHandleSys = NULL; /**< Handle system */ IHandleSys *handlesys = NULL; /**< Handle system */ #endif #if defined SMEXT_ENABLE_PLAYERHELPERS -IPlayerHelpers *playerhelpers = NULL; /**< Player helpers */ +IPlayerManager *playerhelpers = NULL; /**< Player helpers */ #endif //SMEXT_ENABLE_PLAYERHELPERS #if defined SMEXT_ENABLE_DBMANAGER IDBManager *dbi = NULL; /**< DB Manager */ #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 */ PLATFORM_EXTERN_C IExtensionInterface *GetSMExtAPI() @@ -94,6 +112,24 @@ bool SDKExtension::OnExtensionLoad(IExtension *me, IShareSys *sys, char *error, #if defined SMEXT_ENABLE_DBMANAGER SM_GET_IFACE(DBI, dbi); #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)) { diff --git a/extensions/mysql/sdk/smsdk_ext.h b/extensions/mysql/sdk/smsdk_ext.h index d5877cdd..2086f314 100644 --- a/extensions/mysql/sdk/smsdk_ext.h +++ b/extensions/mysql/sdk/smsdk_ext.h @@ -13,7 +13,7 @@ * * 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_ @@ -39,6 +39,24 @@ #if defined SMEXT_ENABLE_DBMANAGER #include #endif //SMEXT_ENABLE_DBMANAGER +#if defined SMEXT_ENABLE_GAMECONF +#include +#endif +#if defined SMEXT_ENABLE_MEMUTILS +#include +#endif +#if defined SMEXT_ENABLE_GAMEHELPERS +#include +#endif +#if defined SMEXT_ENABLE_TIMERSYS +#include +#endif +#if defined SMEXT_ENABLE_ADTFACTORY +#include +#endif +#if defined SMEXT_ENABLE_THREADER +#include +#endif #if defined SMEXT_CONF_METAMOD #include @@ -196,11 +214,29 @@ extern IHandleSys *g_pHandleSys; extern IHandleSys *handlesys; /* Note: Newer name */ #endif //SMEXT_ENABLE_HANDLESYS #if defined SMEXT_ENABLE_PLAYERHELPERS -extern IPlayerHelpers *playerhelpers; +extern IPlayerManager *playerhelpers; #endif //SMEXT_ENABLE_PLAYERHELPERS #if defined SMEXT_ENABLE_DBMANAGER extern IDBManager *dbi; #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 PLUGIN_GLOBALVARS(); diff --git a/public/IDBDriver.h b/public/IDBDriver.h index f99673ac..13e2db63 100644 --- a/public/IDBDriver.h +++ b/public/IDBDriver.h @@ -24,7 +24,7 @@ #include #define SMINTERFACE_DBI_NAME "IDBI" -#define SMINTERFACE_DBI_VERSION 3 +#define SMINTERFACE_DBI_VERSION 4 namespace SourceMod { @@ -396,6 +396,8 @@ namespace SourceMod virtual unsigned int GetInsertID() =0; }; + class IDBDriver; + /** * @brief Encapsulates a database connection. */ @@ -484,6 +486,28 @@ namespace SourceMod * @return Row insertion ID of the last execute, if any. */ 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. */ 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; public: /** - * @brief Adds a driver to the DBI system. + * @brief Adds a driver to the DBI system. Not thread safe. * * @param pDriver Database driver. */ 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. */ @@ -602,7 +645,7 @@ namespace SourceMod 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 pdr Pointer to store the IDBDriver pointer in. @@ -623,14 +666,14 @@ namespace SourceMod 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. */ 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. * @return IDBDriver pointer for the given index. @@ -638,7 +681,7 @@ namespace SourceMod 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 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; /** - * @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 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 - * will attempt to load it. + * will attempt to load it. This function is not thread safe. * * @param name Driver identifier name. * @return IDBDriver pointer on success, NULL otherwise. @@ -678,7 +722,8 @@ namespace SourceMod 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. */