Add atomic reference counting and port DBI (bug 5876 part 3, r=ds).
authorDavid Anderson <dvander@alliedmods.net>
Fri Aug 23 00:18:13 2013 -0700 (2013-08-23)
changeset 4040b6924c1a1d71
parent 4039 e8b8d660b50c
child 4041 72a666cb56df
Add atomic reference counting and port DBI (bug 5876 part 3, r=ds).
extensions/mysql/mysql/MyBasicResults.cpp
extensions/mysql/mysql/MyBasicResults.h
extensions/mysql/mysql/MyDatabase.cpp
extensions/mysql/mysql/MyDatabase.h
extensions/mysql/mysql/MyDriver.cpp
extensions/mysql/mysql/MyDriver.h
extensions/mysql/mysql/MyStatement.cpp
extensions/mysql/mysql/MyStatement.h
extensions/mysql/sdk/smsdk_config.h
extensions/sqlite/driver/SqDatabase.cpp
extensions/sqlite/driver/SqDatabase.h
extensions/sqlite/driver/SqDriver.cpp
extensions/sqlite/driver/SqDriver.h
extensions/sqlite/driver/SqQuery.cpp
extensions/sqlite/driver/SqQuery.h
extensions/sqlite/extension.h
extensions/sqlite/sdk/smsdk_config.h
public/IDBDriver.h
public/amtl/am-atomics.h
public/amtl/am-refcounting-threadsafe.h
     1.1 --- a/extensions/mysql/mysql/MyBasicResults.cpp	Fri Aug 23 00:18:12 2013 -0700
     1.2 +++ b/extensions/mysql/mysql/MyBasicResults.cpp	Fri Aug 23 00:18:13 2013 -0700
     1.3 @@ -306,7 +306,6 @@
     1.4  MyQuery::MyQuery(MyDatabase *db, MYSQL_RES *res)
     1.5  : m_pParent(db), m_rs(res)
     1.6  {
     1.7 -	m_pParent->IncReferenceCount();
     1.8  	m_InsertID = m_pParent->GetInsertID();
     1.9  	m_AffectedRows = m_pParent->GetAffectedRows();
    1.10  }
    1.11 @@ -371,9 +370,6 @@
    1.12  		mysql_free_result(m_rs.m_pRes);
    1.13  	}
    1.14  
    1.15 -	/* Tell our parent we're done */
    1.16 -	m_pParent->Close();
    1.17 -
    1.18  	/* Self destruct */
    1.19  	delete this;
    1.20  }
     2.1 --- a/extensions/mysql/mysql/MyBasicResults.h	Fri Aug 23 00:18:12 2013 -0700
     2.2 +++ b/extensions/mysql/mysql/MyBasicResults.h	Fri Aug 23 00:18:13 2013 -0700
     2.3 @@ -1,5 +1,5 @@
     2.4  /**
     2.5 - * vim: set ts=4 :
     2.6 + * vim: set ts=4 sw=4 tw=99 noet :
     2.7   * =============================================================================
     2.8   * SourceMod MySQL Extension
     2.9   * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    2.10 @@ -91,7 +91,7 @@
    2.11  	unsigned int GetInsertID();
    2.12  	unsigned int GetAffectedRows();
    2.13  private:
    2.14 -	MyDatabase *m_pParent;
    2.15 +	ke::Ref<MyDatabase> m_pParent;
    2.16  	MyBasicResults m_rs;
    2.17  	unsigned int m_InsertID;
    2.18  	unsigned int m_AffectedRows;
     3.1 --- a/extensions/mysql/mysql/MyDatabase.cpp	Fri Aug 23 00:18:12 2013 -0700
     3.2 +++ b/extensions/mysql/mysql/MyDatabase.cpp	Fri Aug 23 00:18:13 2013 -0700
     3.3 @@ -1,5 +1,5 @@
     3.4  /**
     3.5 - * vim: set ts=4 :
     3.6 + * vim: set ts=4 sw=4 tw=99 noet :
     3.7   * =============================================================================
     3.8   * SourceMod MySQL Extension
     3.9   * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    3.10 @@ -87,7 +87,7 @@
    3.11  }
    3.12  
    3.13  MyDatabase::MyDatabase(MYSQL *mysql, const DatabaseInfo *info, bool persistent)
    3.14 -: m_mysql(mysql), m_refcount(1), m_pFullLock(NULL), m_bPersistent(persistent)
    3.15 +: m_mysql(mysql), m_bPersistent(persistent)
    3.16  {
    3.17  	m_Host.assign(info->host);
    3.18  	m_Database.assign(info->database);
    3.19 @@ -101,50 +101,24 @@
    3.20  	m_Info.driver = NULL;
    3.21  	m_Info.maxTimeout = info->maxTimeout;
    3.22  	m_Info.port = info->port;
    3.23 -
    3.24 -	m_pRefLock = threader->MakeMutex();
    3.25  }
    3.26  
    3.27  MyDatabase::~MyDatabase()
    3.28  {
    3.29 +	/* Remove us from the search list */
    3.30 +	if (m_bPersistent)
    3.31 +		g_MyDriver.RemoveFromList(this, true);
    3.32  	mysql_close(m_mysql);
    3.33 -	m_mysql = NULL;
    3.34 -
    3.35 -	m_pRefLock->DestroyThis();
    3.36 -	if (m_pFullLock)
    3.37 -	{
    3.38 -		m_pFullLock->DestroyThis();
    3.39 -	}
    3.40  }
    3.41  
    3.42  void MyDatabase::IncReferenceCount()
    3.43  {
    3.44 -	m_pRefLock->Lock();
    3.45 -	m_refcount++;
    3.46 -	m_pRefLock->Unlock();
    3.47 +	AddRef();
    3.48  }
    3.49  
    3.50  bool MyDatabase::Close()
    3.51  {
    3.52 -	m_pRefLock->Lock();
    3.53 -	if (m_refcount > 1)
    3.54 -	{
    3.55 -		m_refcount--;
    3.56 -		m_pRefLock->Unlock();
    3.57 -		return false;
    3.58 -	}
    3.59 -	m_pRefLock->Unlock();
    3.60 -
    3.61 -	/* Remove us from the search list */
    3.62 -	if (m_bPersistent)
    3.63 -	{
    3.64 -		g_MyDriver.RemoveFromList(this, true);
    3.65 -	}
    3.66 -
    3.67 -	/* Finally, free our resource(s) */
    3.68 -	delete this;
    3.69 -
    3.70 -	return true;
    3.71 +	return !Release();
    3.72  }
    3.73  
    3.74  const DatabaseInfo &MyDatabase::GetInfo()
    3.75 @@ -300,26 +274,17 @@
    3.76  
    3.77  bool MyDatabase::LockForFullAtomicOperation()
    3.78  {
    3.79 -	if (!m_pFullLock)
    3.80 -	{
    3.81 -		m_pFullLock = threader->MakeMutex();
    3.82 -		if (!m_pFullLock)
    3.83 -		{
    3.84 -			return false;
    3.85 -		}
    3.86 -	}
    3.87 +	if (!m_FullLock)
    3.88 +		m_FullLock = new ke::Mutex();
    3.89  
    3.90 -	m_pFullLock->Lock();
    3.91 -
    3.92 +	m_FullLock->Lock();
    3.93  	return true;
    3.94  }
    3.95  
    3.96  void MyDatabase::UnlockFromFullAtomicOperation()
    3.97  {
    3.98 -	if (m_pFullLock)
    3.99 -	{
   3.100 -		m_pFullLock->Unlock();
   3.101 -	}
   3.102 +	if (m_FullLock)
   3.103 +		m_FullLock->Unlock();
   3.104  }
   3.105  
   3.106  IDBDriver *MyDatabase::GetDriver()
   3.107 @@ -330,4 +295,4 @@
   3.108  bool MyDatabase::SetCharacterSet(const char *characterset)
   3.109  {
   3.110  	return mysql_set_character_set(m_mysql, characterset) == 0 ? true : false;
   3.111 -}
   3.112 \ No newline at end of file
   3.113 +}
     4.1 --- a/extensions/mysql/mysql/MyDatabase.h	Fri Aug 23 00:18:12 2013 -0700
     4.2 +++ b/extensions/mysql/mysql/MyDatabase.h	Fri Aug 23 00:18:13 2013 -0700
     4.3 @@ -1,5 +1,5 @@
     4.4  /**
     4.5 - * vim: set ts=4 :
     4.6 + * vim: set ts=4 sw=4 tw=99 noet :
     4.7   * =============================================================================
     4.8   * SourceMod MySQL Extension
     4.9   * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    4.10 @@ -32,13 +32,16 @@
    4.11  #ifndef _INCLUDE_SM_MYSQL_DATABASE_H_
    4.12  #define _INCLUDE_SM_MYSQL_DATABASE_H_
    4.13  
    4.14 +#include <am-thread-utils.h>
    4.15 +#include <am-refcounting-threadsafe.h>
    4.16  #include "MyDriver.h"
    4.17 -#include <IThreader.h>
    4.18  
    4.19  class MyQuery;
    4.20  class MyStatement;
    4.21  
    4.22 -class MyDatabase : public IDatabase
    4.23 +class MyDatabase
    4.24 +	: public IDatabase,
    4.25 +	  public ke::RefcountedThreadsafe<MyDatabase>
    4.26  {
    4.27  	friend class MyQuery;
    4.28  	friend class MyStatement;
    4.29 @@ -67,9 +70,7 @@
    4.30  	const DatabaseInfo &GetInfo();
    4.31  private:
    4.32  	MYSQL *m_mysql;
    4.33 -	unsigned int m_refcount;
    4.34 -	IMutex *m_pFullLock;
    4.35 -	IMutex *m_pRefLock;
    4.36 +	ke::AutoPtr<ke::Mutex> m_FullLock;
    4.37  
    4.38  	/* ---------- */
    4.39  	DatabaseInfo m_Info;
     5.1 --- a/extensions/mysql/mysql/MyDriver.cpp	Fri Aug 23 00:18:12 2013 -0700
     5.2 +++ b/extensions/mysql/mysql/MyDriver.cpp	Fri Aug 23 00:18:13 2013 -0700
     5.3 @@ -1,5 +1,5 @@
     5.4  /**
     5.5 - * vim: set ts=4 :
     5.6 + * vim: set ts=4 sw=4 tw=99 noet :
     5.7   * =============================================================================
     5.8   * SourceMod MySQL Extension
     5.9   * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    5.10 @@ -154,6 +154,8 @@
    5.11  
    5.12  IDatabase *MyDriver::Connect(const DatabaseInfo *info, bool persistent, char *error, size_t maxlength)
    5.13  {
    5.14 +	ke::AutoLock lock(&m_Lock);
    5.15 +
    5.16  	if (persistent)
    5.17  	{
    5.18  		/* Try to find a matching persistent connection */
    5.19 @@ -194,6 +196,7 @@
    5.20  
    5.21  void MyDriver::RemoveFromList(MyDatabase *pdb, bool persistent)
    5.22  {
    5.23 +	ke::AutoLock lock(&m_Lock);
    5.24  	if (persistent)
    5.25  	{
    5.26  		m_PermDbs.remove(pdb);
     6.1 --- a/extensions/mysql/mysql/MyDriver.h	Fri Aug 23 00:18:12 2013 -0700
     6.2 +++ b/extensions/mysql/mysql/MyDriver.h	Fri Aug 23 00:18:13 2013 -0700
     6.3 @@ -1,5 +1,5 @@
     6.4  /**
     6.5 - * vim: set ts=4 :
     6.6 + * vim: set ts=4 sw=4 tw=99 noet :
     6.7   * =============================================================================
     6.8   * SourceMod MySQL Extension
     6.9   * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    6.10 @@ -32,6 +32,7 @@
    6.11  #ifndef _INCLUDE_SM_MYSQL_DRIVER_H_
    6.12  #define _INCLUDE_SM_MYSQL_DRIVER_H_
    6.13  
    6.14 +#define SOURCEMOD_SQL_DRIVER_CODE
    6.15  #include <IDBDriver.h>
    6.16  #include <sm_platform.h>
    6.17  #if defined PLATFORM_WINDOWS
    6.18 @@ -46,6 +47,7 @@
    6.19  
    6.20  #include <sh_string.h>
    6.21  #include <sh_list.h>
    6.22 +#include <am-thread-utils.h>
    6.23  
    6.24  using namespace SourceMod;
    6.25  using namespace SourceHook;
    6.26 @@ -71,6 +73,7 @@
    6.27  	void Shutdown();
    6.28  	void RemoveFromList(MyDatabase *pdb, bool persistent);
    6.29  private:
    6.30 +	ke::Mutex m_Lock;
    6.31  	Handle_t m_MyHandle;
    6.32  	List<MyDatabase *> m_TempDbs;
    6.33  	List<MyDatabase *> m_PermDbs;
     7.1 --- a/extensions/mysql/mysql/MyStatement.cpp	Fri Aug 23 00:18:12 2013 -0700
     7.2 +++ b/extensions/mysql/mysql/MyStatement.cpp	Fri Aug 23 00:18:13 2013 -0700
     7.3 @@ -48,8 +48,6 @@
     7.4  		m_bind = NULL;
     7.5  	}
     7.6  
     7.7 -	m_pParent->IncReferenceCount();
     7.8 -
     7.9  	m_pRes = mysql_stmt_result_metadata(stmt);
    7.10  	m_Results = false;
    7.11  }
    7.12 @@ -75,9 +73,6 @@
    7.13  		mysql_free_result(m_pRes);
    7.14  	}
    7.15  	mysql_stmt_close(m_stmt);
    7.16 -
    7.17 -	/* Tell the parent database that we're done referencing it */
    7.18 -	m_pParent->Close();
    7.19  }
    7.20  
    7.21  void MyStatement::Destroy()
     8.1 --- a/extensions/mysql/mysql/MyStatement.h	Fri Aug 23 00:18:12 2013 -0700
     8.2 +++ b/extensions/mysql/mysql/MyStatement.h	Fri Aug 23 00:18:13 2013 -0700
     8.3 @@ -1,5 +1,5 @@
     8.4  /**
     8.5 - * vim: set ts=4 :
     8.6 + * vim: set ts=4 sw=4 tw=99 noet :
     8.7   * =============================================================================
     8.8   * SourceMod MySQL Extension
     8.9   * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    8.10 @@ -69,7 +69,7 @@
    8.11  	void *CopyBlob(unsigned int param, const void *blobptr, size_t length);
    8.12  private:
    8.13  	MYSQL *m_mysql;
    8.14 -	MyDatabase *m_pParent;
    8.15 +	ke::Ref<MyDatabase> m_pParent;
    8.16  	MYSQL_STMT *m_stmt;
    8.17  	MYSQL_BIND *m_bind;
    8.18  	MYSQL_RES *m_pRes;
     9.1 --- a/extensions/mysql/sdk/smsdk_config.h	Fri Aug 23 00:18:12 2013 -0700
     9.2 +++ b/extensions/mysql/sdk/smsdk_config.h	Fri Aug 23 00:18:13 2013 -0700
     9.3 @@ -67,6 +67,6 @@
     9.4  //#define SMEXT_ENABLE_MEMUTILS
     9.5  //#define SMEXT_ENABLE_GAMEHELPERS
     9.6  //#define SMEXT_ENABLE_TIMERSYS
     9.7 -#define SMEXT_ENABLE_THREADER
     9.8 +//#define SMEXT_ENABLE_THREADER
     9.9  
    9.10  #endif // _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
    10.1 --- a/extensions/sqlite/driver/SqDatabase.cpp	Fri Aug 23 00:18:12 2013 -0700
    10.2 +++ b/extensions/sqlite/driver/SqDatabase.cpp	Fri Aug 23 00:18:13 2013 -0700
    10.3 @@ -1,5 +1,5 @@
    10.4  /**
    10.5 - * vim: set ts=4 :
    10.6 + * vim: set ts=4 sw=4 tw=99 noet :
    10.7   * =============================================================================
    10.8   * SourceMod SQLite Extension
    10.9   * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
   10.10 @@ -34,47 +34,25 @@
   10.11  #include "SqQuery.h"
   10.12  
   10.13  SqDatabase::SqDatabase(sqlite3 *sq3, bool persistent) : 
   10.14 -	m_sq3(sq3), m_refcount(1), m_pFullLock(NULL), m_Persistent(persistent)
   10.15 +	m_sq3(sq3), m_Persistent(persistent)
   10.16  {
   10.17 -	m_pRefLock = threader->MakeMutex();
   10.18  }
   10.19  
   10.20  SqDatabase::~SqDatabase()
   10.21  {
   10.22 -	m_pRefLock->DestroyThis();
   10.23 -	if (m_pFullLock)
   10.24 -	{
   10.25 -		m_pFullLock->DestroyThis();
   10.26 -	}
   10.27 +	if (m_Persistent)
   10.28 +		g_SqDriver.RemovePersistent(this);
   10.29  	sqlite3_close(m_sq3);
   10.30  }
   10.31  
   10.32  void SqDatabase::IncReferenceCount()
   10.33  {
   10.34 -	m_pRefLock->Lock();
   10.35 -	m_refcount++;
   10.36 -	m_pRefLock->Unlock();
   10.37 +	AddRef();
   10.38  }
   10.39  
   10.40  bool SqDatabase::Close()
   10.41  {
   10.42 -	m_pRefLock->Lock();
   10.43 -	if (m_refcount > 1)
   10.44 -	{
   10.45 -		m_refcount--;
   10.46 -		m_pRefLock->Unlock();
   10.47 -		return false;
   10.48 -	}
   10.49 -	m_pRefLock->Unlock();
   10.50 -
   10.51 -	if (m_Persistent)
   10.52 -	{
   10.53 -		g_SqDriver.RemovePersistent(this);
   10.54 -	}
   10.55 -
   10.56 -	delete this;
   10.57 -
   10.58 -	return true;
   10.59 +	return !Release();
   10.60  }
   10.61  
   10.62  const char *SqDatabase::GetError(int *errorCode/* =NULL */)
   10.63 @@ -84,26 +62,17 @@
   10.64  
   10.65  bool SqDatabase::LockForFullAtomicOperation()
   10.66  {
   10.67 -	if (!m_pFullLock)
   10.68 -	{
   10.69 -		m_pFullLock = threader->MakeMutex();
   10.70 -		if (!m_pFullLock)
   10.71 -		{
   10.72 -			return false;
   10.73 -		}
   10.74 -	}
   10.75 +	if (!m_FullLock)
   10.76 +		m_FullLock = new ke::Mutex();
   10.77  
   10.78 -	m_pFullLock->Lock();
   10.79 -
   10.80 +	m_FullLock->Lock();
   10.81  	return true;
   10.82  }
   10.83  
   10.84  void SqDatabase::UnlockFromFullAtomicOperation()
   10.85  {
   10.86 -	if (m_pFullLock)
   10.87 -	{
   10.88 -		m_pFullLock->Unlock();
   10.89 -	}
   10.90 +	if (m_FullLock)
   10.91 +		m_FullLock->Unlock();
   10.92  }
   10.93  
   10.94  IDBDriver *SqDatabase::GetDriver()
   10.95 @@ -259,4 +228,4 @@
   10.96  {
   10.97  	// sqlite only supports utf8 and utf16 - by the time the database is created. It's too late here.
   10.98  	return false;
   10.99 -}
  10.100 \ No newline at end of file
  10.101 +}
    11.1 --- a/extensions/sqlite/driver/SqDatabase.h	Fri Aug 23 00:18:12 2013 -0700
    11.2 +++ b/extensions/sqlite/driver/SqDatabase.h	Fri Aug 23 00:18:13 2013 -0700
    11.3 @@ -1,5 +1,5 @@
    11.4  /**
    11.5 - * vim: set ts=4 :
    11.6 + * vim: set ts=4 sw=4 tw=99 noet :
    11.7   * =============================================================================
    11.8   * SourceMod SQLite Extension
    11.9   * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
   11.10 @@ -32,10 +32,13 @@
   11.11  #ifndef _INCLUDE_SQLITE_SOURCEMOD_DATABASE_H_
   11.12  #define _INCLUDE_SQLITE_SOURCEMOD_DATABASE_H_
   11.13  
   11.14 -#include <IThreader.h>
   11.15 +#include <am-refcounting-threadsafe.h>
   11.16 +#include <am-thread-utils.h>
   11.17  #include "SqDriver.h"
   11.18  
   11.19 -class SqDatabase : public IDatabase
   11.20 +class SqDatabase
   11.21 +	: public IDatabase,
   11.22 +	  public ke::RefcountedThreadsafe<SqDatabase>
   11.23  {
   11.24  public:
   11.25  	SqDatabase(sqlite3 *sq3, bool persistent);
   11.26 @@ -63,9 +66,7 @@
   11.27  	sqlite3 *GetDb();
   11.28  private:
   11.29  	sqlite3 *m_sq3;
   11.30 -	unsigned int m_refcount;
   11.31 -	IMutex *m_pFullLock;
   11.32 -	IMutex *m_pRefLock;
   11.33 +	ke::AutoPtr<ke::Mutex> m_FullLock;
   11.34  	bool m_Persistent;
   11.35  	String m_LastError;
   11.36  	int m_LastErrorCode;
    12.1 --- a/extensions/sqlite/driver/SqDriver.cpp	Fri Aug 23 00:18:12 2013 -0700
    12.2 +++ b/extensions/sqlite/driver/SqDriver.cpp	Fri Aug 23 00:18:13 2013 -0700
    12.3 @@ -1,5 +1,5 @@
    12.4  /**
    12.5 - * vim: set ts=4 :
    12.6 + * vim: set ts=4 sw=4 tw=99 noet :
    12.7   * =============================================================================
    12.8   * SourceMod SQLite Extension
    12.9   * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
   12.10 @@ -66,24 +66,16 @@
   12.11  SqDriver::SqDriver()
   12.12  {
   12.13  	m_Handle = BAD_HANDLE;
   12.14 -	m_pOpenLock = NULL;
   12.15  	m_bThreadSafe = false;
   12.16  }
   12.17  
   12.18  void SqDriver::Initialize()
   12.19  {
   12.20 -	m_pOpenLock = threader->MakeMutex();
   12.21 -
   12.22  	InitializeThreadSafety();
   12.23  }
   12.24  
   12.25  void SqDriver::Shutdown()
   12.26  {
   12.27 -	if (m_pOpenLock)
   12.28 -	{
   12.29 -		m_pOpenLock->DestroyThis();
   12.30 -	}
   12.31 -
   12.32  	if (m_bThreadSafe)
   12.33  	{
   12.34  		sqlite3_enable_shared_cache(0);
   12.35 @@ -158,8 +150,7 @@
   12.36  
   12.37  IDatabase *SqDriver::Connect(const DatabaseInfo *info, bool persistent, char *error, size_t maxlength)
   12.38  {
   12.39 -	/* We wrap most of the open process in a mutex just to be safe */
   12.40 -	m_pOpenLock->Lock();
   12.41 +	ke::AutoLock lock(&m_OpenLock);
   12.42  
   12.43  	/* Format our path */
   12.44  	char path[PLATFORM_MAX_PATH];
   12.45 @@ -189,7 +180,6 @@
   12.46  			if (!libsys->CreateFolder(fullpath))
   12.47  			{
   12.48  				strncopy(error, "Could not create or open \"data\" folder\"", maxlength);
   12.49 -				m_pOpenLock->Unlock();
   12.50  				return NULL;
   12.51  			}
   12.52  		}
   12.53 @@ -237,7 +227,6 @@
   12.54  			if ((*iter).path.compare(fullpath) == 0)
   12.55  			{
   12.56  				(*iter).db->IncReferenceCount();
   12.57 -				m_pOpenLock->Unlock();
   12.58  				return (*iter).db;
   12.59  			}
   12.60  		}
   12.61 @@ -250,7 +239,6 @@
   12.62  	{
   12.63  		strncopy(error, sqlite3_errmsg(sql), maxlength);
   12.64  		sqlite3_close(sql);
   12.65 -		m_pOpenLock->Unlock();
   12.66  		return NULL;
   12.67  	}
   12.68  
   12.69 @@ -266,13 +254,13 @@
   12.70  		m_Cache.push_back(pinfo);
   12.71  	}
   12.72  
   12.73 -	m_pOpenLock->Unlock();
   12.74 -
   12.75  	return pdb;
   12.76  }
   12.77  
   12.78  void SqDriver::RemovePersistent(IDatabase *pdb)
   12.79  {
   12.80 +	ke::AutoLock lock(&m_OpenLock);
   12.81 +
   12.82  	List<SqDbInfo>::iterator iter;
   12.83  	for (iter = m_Cache.begin(); iter != m_Cache.end(); iter++)
   12.84  	{
    13.1 --- a/extensions/sqlite/driver/SqDriver.h	Fri Aug 23 00:18:12 2013 -0700
    13.2 +++ b/extensions/sqlite/driver/SqDriver.h	Fri Aug 23 00:18:13 2013 -0700
    13.3 @@ -1,5 +1,5 @@
    13.4  /**
    13.5 - * vim: set ts=4 :
    13.6 + * vim: set ts=4 sw=4 tw=99 noet :
    13.7   * =============================================================================
    13.8   * SourceMod SQLite Extension
    13.9   * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
   13.10 @@ -32,10 +32,11 @@
   13.11  #ifndef _INCLUDE_SQLITE_SOURCEMOD_DRIVER_H_
   13.12  #define _INCLUDE_SQLITE_SOURCEMOD_DRIVER_H_
   13.13  
   13.14 +#define SOURCEMOD_SQL_DRIVER_CODE
   13.15  #include <IDBDriver.h>
   13.16 -#include <IThreader.h>
   13.17  #include <sh_list.h>
   13.18  #include <sh_string.h>
   13.19 +#include <am-thread-utils.h>
   13.20  #include "sqlite-source/sqlite3.h"
   13.21  
   13.22  using namespace SourceMod;
   13.23 @@ -70,7 +71,7 @@
   13.24  	void RemovePersistent(IDatabase *pdb);
   13.25  private:
   13.26  	Handle_t m_Handle;
   13.27 -	IMutex *m_pOpenLock;
   13.28 +	ke::Mutex m_OpenLock;
   13.29  	List<SqDbInfo> m_Cache;
   13.30  	bool m_bThreadSafe;
   13.31  };
    14.1 --- a/extensions/sqlite/driver/SqQuery.cpp	Fri Aug 23 00:18:12 2013 -0700
    14.2 +++ b/extensions/sqlite/driver/SqQuery.cpp	Fri Aug 23 00:18:13 2013 -0700
    14.3 @@ -36,14 +36,12 @@
    14.4  {
    14.5  	m_ParamCount = sqlite3_bind_parameter_count(m_pStmt);
    14.6  	m_ColCount = sqlite3_column_count(m_pStmt);
    14.7 -	m_pParent->IncReferenceCount();
    14.8  }
    14.9  
   14.10  SqQuery::~SqQuery()
   14.11  {
   14.12  	delete m_pResults;
   14.13  	sqlite3_finalize(m_pStmt);
   14.14 -	m_pParent->Close();
   14.15  }
   14.16  
   14.17  IResultSet *SqQuery::GetResultSet()
    15.1 --- a/extensions/sqlite/driver/SqQuery.h	Fri Aug 23 00:18:12 2013 -0700
    15.2 +++ b/extensions/sqlite/driver/SqQuery.h	Fri Aug 23 00:18:13 2013 -0700
    15.3 @@ -1,5 +1,5 @@
    15.4  /**
    15.5 - * vim: set ts=4 :
    15.6 + * vim: set ts=4 sw=4 tw=99 noet :
    15.7   * =============================================================================
    15.8   * SourceMod SQLite Extension
    15.9   * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
   15.10 @@ -32,6 +32,7 @@
   15.11  #ifndef _INCLUDE_SQLITE_SOURCEMOD_QUERY_H_
   15.12  #define _INCLUDE_SQLITE_SOURCEMOD_QUERY_H_
   15.13  
   15.14 +#include <am-refcounting.h>
   15.15  #include "SqDatabase.h"
   15.16  #include "SqResults.h"
   15.17  
   15.18 @@ -81,7 +82,7 @@
   15.19  public:
   15.20  	sqlite3_stmt *GetStmt();
   15.21  private:
   15.22 -	SqDatabase *m_pParent;
   15.23 +	ke::Ref<SqDatabase> m_pParent;
   15.24  	sqlite3_stmt *m_pStmt;
   15.25  	SqResults *m_pResults;
   15.26  	unsigned int m_ParamCount;
    16.1 --- a/extensions/sqlite/extension.h	Fri Aug 23 00:18:12 2013 -0700
    16.2 +++ b/extensions/sqlite/extension.h	Fri Aug 23 00:18:13 2013 -0700
    16.3 @@ -37,6 +37,7 @@
    16.4   * @brief Sample extension code header.
    16.5   */
    16.6  
    16.7 +#define SOURCEMOD_SQL_DRIVER_CODE
    16.8  #include "smsdk_ext.h"
    16.9  
   16.10  
    17.1 --- a/extensions/sqlite/sdk/smsdk_config.h	Fri Aug 23 00:18:12 2013 -0700
    17.2 +++ b/extensions/sqlite/sdk/smsdk_config.h	Fri Aug 23 00:18:13 2013 -0700
    17.3 @@ -67,7 +67,7 @@
    17.4  //#define SMEXT_ENABLE_MEMUTILS
    17.5  //#define SMEXT_ENABLE_GAMEHELPERS
    17.6  //#define SMEXT_ENABLE_TIMERSYS
    17.7 -#define SMEXT_ENABLE_THREADER
    17.8 +//#define SMEXT_ENABLE_THREADER
    17.9  #define SMEXT_ENABLE_LIBSYS
   17.10  
   17.11  #endif // _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
    18.1 --- a/public/IDBDriver.h	Fri Aug 23 00:18:12 2013 -0700
    18.2 +++ b/public/IDBDriver.h	Fri Aug 23 00:18:13 2013 -0700
    18.3 @@ -608,6 +608,7 @@
    18.4  		 */
    18.5  		virtual bool SetCharacterSet(const char *characterset) =0;
    18.6  
    18.7 +#if !defined(SOURCEMOD_SQL_DRIVER_CODE)
    18.8  		/**
    18.9  		 * @brief Wrapper around IncReferenceCount(), for ke::Ref.
   18.10  		 */
   18.11 @@ -621,6 +622,7 @@
   18.12  		void Release() {
   18.13  			Close();
   18.14  		}
   18.15 +#endif
   18.16  	};
   18.17  
   18.18  	/** 
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/public/amtl/am-atomics.h	Fri Aug 23 00:18:13 2013 -0700
    19.3 @@ -0,0 +1,100 @@
    19.4 +// vim: set sts=8 ts=2 sw=2 tw=99 et:
    19.5 +//
    19.6 +// Copyright (C) 2013, David Anderson and AlliedModders LLC
    19.7 +// All rights reserved.
    19.8 +// 
    19.9 +// Redistribution and use in source and binary forms, with or without
   19.10 +// modification, are permitted provided that the following conditions are met:
   19.11 +// 
   19.12 +//  * Redistributions of source code must retain the above copyright notice, this
   19.13 +//    list of conditions and the following disclaimer.
   19.14 +//  * Redistributions in binary form must reproduce the above copyright notice,
   19.15 +//    this list of conditions and the following disclaimer in the documentation
   19.16 +//    and/or other materials provided with the distribution.
   19.17 +//  * Neither the name of AlliedModders LLC nor the names of its contributors
   19.18 +//    may be used to endorse or promote products derived from this software
   19.19 +//    without specific prior written permission.
   19.20 +//
   19.21 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   19.22 +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19.23 +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19.24 +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   19.25 +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   19.26 +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   19.27 +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   19.28 +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   19.29 +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   19.30 +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   19.31 +// POSSIBILITY OF SUCH DAMAGE.
   19.32 +
   19.33 +#ifndef _include_amtl_atomics_h_
   19.34 +#define _include_amtl_atomics_h_
   19.35 +
   19.36 +#include <am-utility.h>
   19.37 +
   19.38 +namespace ke {
   19.39 +
   19.40 +#if defined(_MSC_VER)
   19.41 +extern "C" {
   19.42 +  long __cdecl _InterlockedIncrement(long volatile *dest);
   19.43 +  long __cdecl _InterlockedDecrement(long volatile *dest);
   19.44 +}
   19.45 +# pragma intrinsic(_InterlockedIncrement);
   19.46 +# pragma intrinsic(_InterlockedDecrement);
   19.47 +#endif
   19.48 +
   19.49 +template <size_t Width>
   19.50 +struct AtomicOps;
   19.51 +
   19.52 +template <>
   19.53 +struct AtomicOps<4>
   19.54 +{
   19.55 +  typedef int Type;
   19.56 +
   19.57 +#if defined(_MSC_VER)
   19.58 +  static int Increment(int *ptr) {
   19.59 +    return _InterlockedIncrement(ptr);
   19.60 +  }
   19.61 +  static int Decrement(int *ptr) {
   19.62 +    return _InterlockedDecrement(ptr);
   19.63 +  };
   19.64 +#elif defined(__GNUC__)
   19.65 +  // x86/x64 notes: When using GCC < 4.8, this will compile to a spinlock.
   19.66 +  // On 4.8+, or when using Clang, we'll get the more optimal "lock addl"
   19.67 +  // variant.
   19.68 +  static int Increment(int *ptr) {
   19.69 +    return __sync_add_and_fetch(ptr, 1);
   19.70 +  }
   19.71 +  static int Decrement(int *ptr) {
   19.72 +    return __sync_sub_and_fetch(ptr, 1);
   19.73 +  }
   19.74 +#endif
   19.75 +};
   19.76 +
   19.77 +class AtomicRefCount
   19.78 +{
   19.79 +  typedef AtomicOps<sizeof(uintptr_t)> Ops;
   19.80 +
   19.81 + public:
   19.82 +  AtomicRefCount(uintptr_t value)
   19.83 +   : value_(value)
   19.84 +  {
   19.85 +  }
   19.86 +
   19.87 +  void increment() {
   19.88 +    Ops::Increment(&value_);
   19.89 +  }
   19.90 +
   19.91 +  // Return false if all references are gone.
   19.92 +  bool decrement() {
   19.93 +    return Ops::Decrement(&value_) != 0;
   19.94 +  }
   19.95 +
   19.96 + private:
   19.97 +  Ops::Type value_;
   19.98 +};
   19.99 +
  19.100 +}
  19.101 +
  19.102 +#endif // _include_amtl_atomics_h_
  19.103 +
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/public/amtl/am-refcounting-threadsafe.h	Fri Aug 23 00:18:13 2013 -0700
    20.3 @@ -0,0 +1,68 @@
    20.4 +// vim: set sts=8 ts=2 sw=2 tw=99 et:
    20.5 +//
    20.6 +// Copyright (C) 2013, David Anderson and AlliedModders LLC
    20.7 +// All rights reserved.
    20.8 +// 
    20.9 +// Redistribution and use in source and binary forms, with or without
   20.10 +// modification, are permitted provided that the following conditions are met:
   20.11 +// 
   20.12 +//  * Redistributions of source code must retain the above copyright notice, this
   20.13 +//    list of conditions and the following disclaimer.
   20.14 +//  * Redistributions in binary form must reproduce the above copyright notice,
   20.15 +//    this list of conditions and the following disclaimer in the documentation
   20.16 +//    and/or other materials provided with the distribution.
   20.17 +//  * Neither the name of AlliedModders LLC nor the names of its contributors
   20.18 +//    may be used to endorse or promote products derived from this software
   20.19 +//    without specific prior written permission.
   20.20 +//
   20.21 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   20.22 +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   20.23 +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20.24 +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   20.25 +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   20.26 +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   20.27 +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   20.28 +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   20.29 +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   20.30 +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   20.31 +// POSSIBILITY OF SUCH DAMAGE.
   20.32 +
   20.33 +#ifndef _include_amtl_ts_refcounting_h_
   20.34 +#define _include_amtl_ts_refcounting_h_
   20.35 +
   20.36 +#include <am-refcounting.h>
   20.37 +#include <am-atomics.h>
   20.38 +
   20.39 +namespace ke {
   20.40 +
   20.41 +template <typename T>
   20.42 +class RefcountedThreadsafe
   20.43 +{
   20.44 +  public:
   20.45 +    RefcountedThreadsafe()
   20.46 +     : refcount_(1)
   20.47 +    {
   20.48 +    }
   20.49 +
   20.50 +    void AddRef() {
   20.51 +      refcount_.increment();
   20.52 +    }
   20.53 +    bool Release() {
   20.54 +        if (!refcount_.decrement()) {
   20.55 +            delete static_cast<T *>(this);
   20.56 +            return false;
   20.57 +        }
   20.58 +        return true;
   20.59 +    }
   20.60 +
   20.61 +  protected:
   20.62 +    ~RefcountedThreadsafe() {
   20.63 +    }
   20.64 +
   20.65 +  private:
   20.66 +    AtomicRefCount refcount_;
   20.67 +};
   20.68 +
   20.69 +} // namespace ke
   20.70 +
   20.71 +#endif // _include_amtl_ts_refcounting_h_