1.1 --- a/core/Database.cpp Fri Mar 28 06:21:34 2008 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,719 +0,0 @@
1.4 -/**
1.5 - * vim: set ts=4 :
1.6 - * =============================================================================
1.7 - * SourceMod
1.8 - * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
1.9 - * =============================================================================
1.10 - *
1.11 - * This program is free software; you can redistribute it and/or modify it under
1.12 - * the terms of the GNU General Public License, version 3.0, as published by the
1.13 - * Free Software Foundation.
1.14 - *
1.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
1.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.18 - * details.
1.19 - *
1.20 - * You should have received a copy of the GNU General Public License along with
1.21 - * this program. If not, see <http://www.gnu.org/licenses/>.
1.22 - *
1.23 - * As a special exception, AlliedModders LLC gives you permission to link the
1.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
1.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
1.26 - * by the Valve Corporation. You must obey the GNU General Public License in
1.27 - * all respects for all other code used. Additionally, AlliedModders LLC grants
1.28 - * this exception to all derivative works. AlliedModders LLC defines further
1.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
1.30 - * or <http://www.sourcemod.net/license.php>.
1.31 - *
1.32 - * Version: $Id$
1.33 - */
1.34 -
1.35 -#include "Database.h"
1.36 -#include "HandleSys.h"
1.37 -#include "ShareSys.h"
1.38 -#include "sourcemod.h"
1.39 -#include "sm_stringutil.h"
1.40 -#include "Logger.h"
1.41 -#include "ExtensionSys.h"
1.42 -#include <stdlib.h>
1.43 -#include "ThreadSupport.h"
1.44 -
1.45 -#define DBPARSE_LEVEL_NONE 0
1.46 -#define DBPARSE_LEVEL_MAIN 1
1.47 -#define DBPARSE_LEVEL_DATABASE 2
1.48 -
1.49 -DBManager g_DBMan;
1.50 -static bool s_OneTimeThreaderErrorMsg = false;
1.51 -
1.52 -DBManager::DBManager()
1.53 -: m_StrTab(512), m_ParseLevel(0), m_ParseState(0), m_pDefault(NULL)
1.54 -{
1.55 -}
1.56 -
1.57 -void DBManager::OnSourceModAllInitialized()
1.58 -{
1.59 - HandleAccess sec;
1.60 -
1.61 - g_HandleSys.InitAccessDefaults(NULL, &sec);
1.62 - sec.access[HandleAccess_Delete] |= HANDLE_RESTRICT_IDENTITY;
1.63 - sec.access[HandleAccess_Clone] |= HANDLE_RESTRICT_IDENTITY;
1.64 -
1.65 - m_DriverType = g_HandleSys.CreateType("IDriver", this, 0, NULL, &sec, g_pCoreIdent, NULL);
1.66 - m_DatabaseType = g_HandleSys.CreateType("IDatabase", this, 0, NULL, NULL, g_pCoreIdent, NULL);
1.67 -
1.68 - g_ShareSys.AddInterface(NULL, this);
1.69 -
1.70 - g_SourceMod.BuildPath(Path_SM, m_Filename, sizeof(m_Filename), "configs/databases.cfg");
1.71 -
1.72 - m_pConfigLock = g_pThreader->MakeMutex();
1.73 - m_pThinkLock = g_pThreader->MakeMutex();
1.74 - m_pQueueLock = g_pThreader->MakeMutex();
1.75 -
1.76 - g_PluginSys.AddPluginsListener(this);
1.77 -}
1.78 -
1.79 -void DBManager::OnSourceModLevelChange(const char *mapName)
1.80 -{
1.81 - SMCError err;
1.82 - SMCStates states = {0, 0};
1.83 -
1.84 - /* We lock and don't give up the lock until we're done.
1.85 - * This way the thread's search won't be searching through a
1.86 - * potentially empty/corrupt list, which would be very bad.
1.87 - */
1.88 - m_pConfigLock->Lock();
1.89 - if ((err = textparsers->ParseFile_SMC(m_Filename, this, &states)) != SMCError_Okay)
1.90 - {
1.91 - g_Logger.LogError("[SM] Detected parse error(s) in file \"%s\"", m_Filename);
1.92 - if (err != SMCError_Custom)
1.93 - {
1.94 - const char *txt = textparsers->GetSMCErrorString(err);
1.95 - g_Logger.LogError("[SM] Line %d: %s", states.line, txt);
1.96 - }
1.97 - }
1.98 - m_pConfigLock->Unlock();
1.99 -}
1.100 -
1.101 -void DBManager::OnSourceModShutdown()
1.102 -{
1.103 - KillWorkerThread();
1.104 - g_PluginSys.RemovePluginsListener(this);
1.105 - m_pConfigLock->DestroyThis();
1.106 - m_pThinkLock->DestroyThis();
1.107 - m_pQueueLock->DestroyThis();
1.108 - g_HandleSys.RemoveType(m_DatabaseType, g_pCoreIdent);
1.109 - g_HandleSys.RemoveType(m_DriverType, g_pCoreIdent);
1.110 -}
1.111 -
1.112 -unsigned int DBManager::GetInterfaceVersion()
1.113 -{
1.114 - return SMINTERFACE_DBI_VERSION;
1.115 -}
1.116 -
1.117 -const char *DBManager::GetInterfaceName()
1.118 -{
1.119 - return SMINTERFACE_DBI_NAME;
1.120 -}
1.121 -
1.122 -void DBManager::OnHandleDestroy(HandleType_t type, void *object)
1.123 -{
1.124 - if (type == m_DriverType)
1.125 - {
1.126 - /* Ignore */
1.127 - return;
1.128 - }
1.129 -
1.130 - if (g_HandleSys.TypeCheck(type, m_DatabaseType))
1.131 - {
1.132 - IDatabase *pdb = (IDatabase *)object;
1.133 - pdb->Close();
1.134 - }
1.135 -}
1.136 -
1.137 -void DBManager::ReadSMC_ParseStart()
1.138 -{
1.139 - m_confs.clear();
1.140 - m_ParseLevel = 0;
1.141 - m_ParseState = DBPARSE_LEVEL_NONE;
1.142 - m_StrTab.Reset();
1.143 - m_DefDriver.clear();
1.144 -}
1.145 -
1.146 -ConfDbInfo s_CurInfo;
1.147 -SMCResult DBManager::ReadSMC_NewSection(const SMCStates *states, const char *name)
1.148 -{
1.149 - if (m_ParseLevel)
1.150 - {
1.151 - m_ParseLevel++;
1.152 - return SMCResult_Continue;
1.153 - }
1.154 -
1.155 - if (m_ParseState == DBPARSE_LEVEL_NONE)
1.156 - {
1.157 - if (strcmp(name, "Databases") == 0)
1.158 - {
1.159 - m_ParseState = DBPARSE_LEVEL_MAIN;
1.160 - } else {
1.161 - m_ParseLevel++;
1.162 - }
1.163 - } else if (m_ParseState == DBPARSE_LEVEL_MAIN) {
1.164 - s_CurInfo = ConfDbInfo();
1.165 - s_CurInfo.name = m_StrTab.AddString(name);
1.166 - m_ParseState = DBPARSE_LEVEL_DATABASE;
1.167 - } else if (m_ParseState == DBPARSE_LEVEL_DATABASE) {
1.168 - m_ParseLevel++;
1.169 - }
1.170 -
1.171 - return SMCResult_Continue;
1.172 -}
1.173 -
1.174 -SMCResult DBManager::ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
1.175 -{
1.176 - if (m_ParseLevel)
1.177 - {
1.178 - return SMCResult_Continue;
1.179 - }
1.180 -
1.181 - if (m_ParseState == DBPARSE_LEVEL_MAIN)
1.182 - {
1.183 - if (strcmp(key, "driver_default") == 0)
1.184 - {
1.185 - m_DefDriver.assign(value);
1.186 - }
1.187 - } else if (m_ParseState == DBPARSE_LEVEL_DATABASE) {
1.188 - if (strcmp(key, "driver") == 0)
1.189 - {
1.190 - if (strcmp(value, "default") != 0)
1.191 - {
1.192 - s_CurInfo.driver = m_StrTab.AddString(value);
1.193 - }
1.194 - } else if (strcmp(key, "database") == 0) {
1.195 - s_CurInfo.database = m_StrTab.AddString(value);
1.196 - } else if (strcmp(key, "host") == 0) {
1.197 - s_CurInfo.host = m_StrTab.AddString(value);
1.198 - } else if (strcmp(key, "user") == 0) {
1.199 - s_CurInfo.user = m_StrTab.AddString(value);
1.200 - } else if (strcmp(key, "pass") == 0) {
1.201 - s_CurInfo.pass = m_StrTab.AddString(value);
1.202 - } else if (strcmp(key, "timeout") == 0) {
1.203 - s_CurInfo.info.maxTimeout = atoi(value);
1.204 - } else if (strcmp(key, "port") == 0) {
1.205 - s_CurInfo.info.port = atoi(value);
1.206 - }
1.207 - }
1.208 -
1.209 - return SMCResult_Continue;
1.210 -}
1.211 -
1.212 -#define ASSIGN_VAR(var) \
1.213 - if (s_CurInfo.var == -1) { \
1.214 - s_CurInfo.info.var = ""; \
1.215 - } else { \
1.216 - s_CurInfo.info.var = m_StrTab.GetString(s_CurInfo.var); \
1.217 - }
1.218 -
1.219 -SMCResult DBManager::ReadSMC_LeavingSection(const SMCStates *states)
1.220 -{
1.221 - if (m_ParseLevel)
1.222 - {
1.223 - m_ParseLevel--;
1.224 - return SMCResult_Continue;
1.225 - }
1.226 -
1.227 - if (m_ParseState == DBPARSE_LEVEL_DATABASE)
1.228 - {
1.229 - /* Set all of the info members to either a blank string
1.230 - * or the string pointer from the string table.
1.231 - */
1.232 - ASSIGN_VAR(driver);
1.233 - ASSIGN_VAR(database);
1.234 - ASSIGN_VAR(host);
1.235 - ASSIGN_VAR(user);
1.236 - ASSIGN_VAR(pass);
1.237 -
1.238 - /* Save it.. */
1.239 - m_confs.push_back(s_CurInfo);
1.240 -
1.241 - /* Go up one level */
1.242 - m_ParseState = DBPARSE_LEVEL_MAIN;
1.243 - } else if (m_ParseState == DBPARSE_LEVEL_MAIN) {
1.244 - m_ParseState = DBPARSE_LEVEL_NONE;
1.245 - return SMCResult_Halt;
1.246 - }
1.247 -
1.248 - return SMCResult_Continue;
1.249 -}
1.250 -#undef ASSIGN_VAR
1.251 -
1.252 -void DBManager::ReadSMC_ParseEnd(bool halted, bool failed)
1.253 -{
1.254 -}
1.255 -
1.256 -bool DBManager::Connect(const char *name, IDBDriver **pdr, IDatabase **pdb, bool persistent, char *error, size_t maxlength)
1.257 -{
1.258 - ConfDbInfo *pInfo = GetDatabaseConf(name);
1.259 -
1.260 - if (!pInfo)
1.261 - {
1.262 - if (pdr)
1.263 - {
1.264 - *pdr = NULL;
1.265 - }
1.266 - *pdb = NULL;
1.267 - UTIL_Format(error, maxlength, "Configuration \"%s\" not found", name);
1.268 - return false;
1.269 - }
1.270 -
1.271 - const char *dname = pInfo->info.driver;
1.272 - if (!pInfo->realDriver)
1.273 - {
1.274 - /* Try to assign a real driver pointer */
1.275 - if (pInfo->info.driver[0] == '\0')
1.276 - {
1.277 - if (!m_pDefault && m_DefDriver.size() > 0)
1.278 - {
1.279 - m_pDefault = FindOrLoadDriver(m_DefDriver.c_str());
1.280 - }
1.281 - dname = m_DefDriver.size() ? m_DefDriver.c_str() : "default";
1.282 - pInfo->realDriver = m_pDefault;
1.283 - } else {
1.284 - pInfo->realDriver = FindOrLoadDriver(pInfo->info.driver);
1.285 - }
1.286 - }
1.287 -
1.288 - if (pInfo->realDriver)
1.289 - {
1.290 - if (pdr)
1.291 - {
1.292 - *pdr = pInfo->realDriver;
1.293 - }
1.294 - *pdb = pInfo->realDriver->Connect(&pInfo->info, persistent, error, maxlength);
1.295 - return (*pdb != NULL);
1.296 - }
1.297 -
1.298 - if (pdr)
1.299 - {
1.300 - *pdr = NULL;
1.301 - }
1.302 - *pdb = NULL;
1.303 -
1.304 - UTIL_Format(error, maxlength, "Driver \"%s\" not found", dname);
1.305 -
1.306 - return false;
1.307 -}
1.308 -
1.309 -void DBManager::AddDriver(IDBDriver *pDriver)
1.310 -{
1.311 - /* Let's kill the worker. Join the thread and let the queries flush.
1.312 - * This is kind of stupid but we just want to unload safely.
1.313 - * Rather than recreate the worker, we'll wait until someone throws
1.314 - * another query through.
1.315 - */
1.316 - KillWorkerThread();
1.317 -
1.318 - m_drivers.push_back(pDriver);
1.319 -}
1.320 -
1.321 -void DBManager::RemoveDriver(IDBDriver *pDriver)
1.322 -{
1.323 - /* Again, we're forced to kill the worker. How rude!
1.324 - * Doing this flushes the queue, and thus we don't need to
1.325 - * clean anything else.
1.326 - */
1.327 - KillWorkerThread();
1.328 -
1.329 - for (size_t i=0; i<m_drivers.size(); i++)
1.330 - {
1.331 - if (m_drivers[i] == pDriver)
1.332 - {
1.333 - m_drivers.erase(m_drivers.iterAt(i));
1.334 - break;
1.335 - }
1.336 - }
1.337 -
1.338 - /* Make sure NOTHING references this! */
1.339 - List<ConfDbInfo>::iterator iter;
1.340 - for (iter=m_confs.begin(); iter!=m_confs.end(); iter++)
1.341 - {
1.342 - ConfDbInfo &db = (*iter);
1.343 - if (db.realDriver == pDriver)
1.344 - {
1.345 - db.realDriver = NULL;
1.346 - }
1.347 - }
1.348 -
1.349 - /* Now that the driver is gone, we have to test the think queue.
1.350 - * Whatever happens therein is up to the db op!
1.351 - */
1.352 - Queue<IDBThreadOperation *>::iterator qiter = m_ThinkQueue.begin();
1.353 - Queue<IDBThreadOperation *> templist;
1.354 - while (qiter != m_ThinkQueue.end())
1.355 - {
1.356 - IDBThreadOperation *op = (*qiter);
1.357 - if (op->GetDriver() == pDriver)
1.358 - {
1.359 - templist.push(op);
1.360 - qiter = m_ThinkQueue.erase(qiter);
1.361 - } else {
1.362 - qiter++;
1.363 - }
1.364 - }
1.365 -
1.366 - for (qiter = templist.begin();
1.367 - qiter != templist.end();
1.368 - qiter++)
1.369 - {
1.370 - IDBThreadOperation *op = (*qiter);
1.371 - op->CancelThinkPart();
1.372 - op->Destroy();
1.373 - }
1.374 -}
1.375 -
1.376 -IDBDriver *DBManager::GetDefaultDriver()
1.377 -{
1.378 - if (!m_pDefault && m_DefDriver.size() > 0)
1.379 - {
1.380 - m_pDefault = FindOrLoadDriver(m_DefDriver.c_str());
1.381 - }
1.382 -
1.383 - return m_pDefault;
1.384 -}
1.385 -
1.386 -Handle_t DBManager::CreateHandle(DBHandleType dtype, void *ptr, IdentityToken_t *pToken)
1.387 -{
1.388 - HandleType_t type = 0;
1.389 -
1.390 - if (dtype == DBHandle_Driver)
1.391 - {
1.392 - type = m_DriverType;
1.393 - } else if (dtype == DBHandle_Database) {
1.394 - type = m_DatabaseType;
1.395 - } else {
1.396 - return BAD_HANDLE;
1.397 - }
1.398 -
1.399 - return g_HandleSys.CreateHandle(type, ptr, pToken, g_pCoreIdent, NULL);
1.400 -}
1.401 -
1.402 -HandleError DBManager::ReadHandle(Handle_t hndl, DBHandleType dtype, void **ptr)
1.403 -{
1.404 - HandleType_t type = 0;
1.405 -
1.406 - if (dtype == DBHandle_Driver)
1.407 - {
1.408 - type = m_DriverType;
1.409 - } else if (dtype == DBHandle_Database) {
1.410 - type = m_DatabaseType;
1.411 - } else {
1.412 - return HandleError_Type;
1.413 - }
1.414 -
1.415 - HandleSecurity sec(NULL, g_pCoreIdent);
1.416 -
1.417 - return g_HandleSys.ReadHandle(hndl, type, &sec, ptr);
1.418 -}
1.419 -
1.420 -HandleError DBManager::ReleaseHandle(Handle_t hndl, DBHandleType type, IdentityToken_t *token)
1.421 -{
1.422 - HandleSecurity sec(token, g_pCoreIdent);
1.423 - return g_HandleSys.FreeHandle(hndl, &sec);
1.424 -}
1.425 -
1.426 -unsigned int DBManager::GetDriverCount()
1.427 -{
1.428 - return (unsigned int)m_drivers.size();
1.429 -}
1.430 -
1.431 -IDBDriver *DBManager::GetDriver(unsigned int index)
1.432 -{
1.433 - if (index >= m_drivers.size())
1.434 - {
1.435 - return NULL;
1.436 - }
1.437 -
1.438 - return m_drivers[index];
1.439 -}
1.440 -
1.441 -const DatabaseInfo *DBManager::FindDatabaseConf(const char *name)
1.442 -{
1.443 - ConfDbInfo *info = GetDatabaseConf(name);
1.444 - if (!info)
1.445 - {
1.446 - return NULL;
1.447 - }
1.448 -
1.449 - return &info->info;
1.450 -}
1.451 -
1.452 -ConfDbInfo *DBManager::GetDatabaseConf(const char *name)
1.453 -{
1.454 - List<ConfDbInfo>::iterator iter;
1.455 -
1.456 - for (iter=m_confs.begin(); iter!=m_confs.end(); iter++)
1.457 - {
1.458 - ConfDbInfo &conf = (*iter);
1.459 - if (strcmp(m_StrTab.GetString(conf.name), name) == 0)
1.460 - {
1.461 - return &conf;
1.462 - }
1.463 - }
1.464 -
1.465 - return NULL;
1.466 -}
1.467 -
1.468 -IDBDriver *DBManager::FindOrLoadDriver(const char *name)
1.469 -{
1.470 - size_t last_size = m_drivers.size();
1.471 - for (size_t i=0; i<last_size; i++)
1.472 - {
1.473 - if (strcmp(m_drivers[i]->GetIdentifier(), name) == 0)
1.474 - {
1.475 - return m_drivers[i];
1.476 - }
1.477 - }
1.478 -
1.479 - char filename[PLATFORM_MAX_PATH];
1.480 - UTIL_Format(filename, sizeof(filename), "dbi.%s.ext", name);
1.481 -
1.482 - IExtension *pExt = g_Extensions.LoadAutoExtension(filename);
1.483 - if (!pExt || !pExt->IsLoaded() || m_drivers.size() <= last_size)
1.484 - {
1.485 - return NULL;
1.486 - }
1.487 -
1.488 - /* last_size is now gauranteed to be a valid index.
1.489 - * The identifier must match the name.
1.490 - */
1.491 - if (strcmp(m_drivers[last_size]->GetIdentifier(), name) == 0)
1.492 - {
1.493 - return m_drivers[last_size];
1.494 - }
1.495 -
1.496 - return NULL;
1.497 -}
1.498 -
1.499 -void DBManager::KillWorkerThread()
1.500 -{
1.501 - if (m_pWorker)
1.502 - {
1.503 - m_pWorker->Stop(false);
1.504 - g_pThreader->DestroyWorker(m_pWorker);
1.505 - m_pWorker = NULL;
1.506 - s_OneTimeThreaderErrorMsg = false;
1.507 - }
1.508 -}
1.509 -
1.510 -static IdentityToken_t *s_pAddBlock = NULL;
1.511 -
1.512 -bool DBManager::AddToThreadQueue(IDBThreadOperation *op, PrioQueueLevel prio)
1.513 -{
1.514 - if (s_pAddBlock && op->GetOwner() == s_pAddBlock)
1.515 - {
1.516 - return false;
1.517 - }
1.518 -
1.519 - if (!m_pWorker)
1.520 - {
1.521 - m_pWorker = g_pThreader->MakeWorker(this, true);
1.522 - if (!m_pWorker)
1.523 - {
1.524 - if (!s_OneTimeThreaderErrorMsg)
1.525 - {
1.526 - g_Logger.LogError("[SM] Unable to create db threader (error unknown)");
1.527 - s_OneTimeThreaderErrorMsg = true;
1.528 - }
1.529 - return false;
1.530 - }
1.531 - if (!m_pWorker->Start())
1.532 - {
1.533 - if (!s_OneTimeThreaderErrorMsg)
1.534 - {
1.535 - g_Logger.LogError("[SM] Unable to start db threader (error unknown)");
1.536 - s_OneTimeThreaderErrorMsg = true;
1.537 - }
1.538 - g_pThreader->DestroyWorker(m_pWorker);
1.539 - m_pWorker = NULL;
1.540 - return false;
1.541 - }
1.542 - }
1.543 -
1.544 - /* Add to the queue */
1.545 - {
1.546 - m_pQueueLock->Lock();
1.547 - Queue<IDBThreadOperation *> &queue = m_OpQueue.GetQueue(prio);
1.548 - queue.push(op);
1.549 - m_pQueueLock->Unlock();
1.550 - }
1.551 -
1.552 - /* Make the thread */
1.553 - m_pWorker->MakeThread(this);
1.554 -
1.555 - return true;
1.556 -}
1.557 -
1.558 -void DBManager::OnWorkerStart(IThreadWorker *pWorker)
1.559 -{
1.560 - m_drSafety.clear();
1.561 - for (size_t i=0; i<m_drivers.size(); i++)
1.562 - {
1.563 - if (m_drivers[i]->IsThreadSafe())
1.564 - {
1.565 - m_drSafety.push_back(m_drivers[i]->InitializeThreadSafety());
1.566 - } else {
1.567 - m_drSafety.push_back(false);
1.568 - }
1.569 - }
1.570 -}
1.571 -
1.572 -void DBManager::OnWorkerStop(IThreadWorker *pWorker)
1.573 -{
1.574 - for (size_t i=0; i<m_drivers.size(); i++)
1.575 - {
1.576 - if (m_drSafety[i])
1.577 - {
1.578 - m_drivers[i]->ShutdownThreadSafety();
1.579 - }
1.580 - }
1.581 - m_drSafety.clear();
1.582 -}
1.583 -
1.584 -void DBManager::RunThread(IThreadHandle *pThread)
1.585 -{
1.586 - IDBThreadOperation *op = NULL;
1.587 -
1.588 - /* Get something from the queue */
1.589 - {
1.590 - m_pQueueLock->Lock();
1.591 - Queue<IDBThreadOperation *> &queue = m_OpQueue.GetLikelyQueue();
1.592 - if (!queue.empty())
1.593 - {
1.594 - op = queue.first();
1.595 - queue.pop();
1.596 - }
1.597 - m_pQueueLock->Unlock();
1.598 - }
1.599 -
1.600 - /* whoa. hi. did we get something? we should have. */
1.601 - if (!op)
1.602 - {
1.603 - /* wtf? */
1.604 - return;
1.605 - }
1.606 -
1.607 - op->RunThreadPart();
1.608 -
1.609 - m_pThinkLock->Lock();
1.610 - m_ThinkQueue.push(op);
1.611 - m_pThinkLock->Unlock();
1.612 -}
1.613 -
1.614 -void DBManager::RunFrame()
1.615 -{
1.616 - /* Don't bother if we're empty */
1.617 - if (!m_ThinkQueue.size())
1.618 - {
1.619 - return;
1.620 - }
1.621 -
1.622 - /* Dump one thing per-frame so the server stays sane. */
1.623 - m_pThinkLock->Lock();
1.624 - IDBThreadOperation *op = m_ThinkQueue.first();
1.625 - m_ThinkQueue.pop();
1.626 - m_pThinkLock->Unlock();
1.627 - op->RunThinkPart();
1.628 - op->Destroy();
1.629 -}
1.630 -
1.631 -void DBManager::OnTerminate(IThreadHandle *pThread, bool cancel)
1.632 -{
1.633 - /* Do nothing */
1.634 -}
1.635 -
1.636 -void DBManager::OnSourceModIdentityDropped(IdentityToken_t *pToken)
1.637 -{
1.638 - s_pAddBlock = pToken;
1.639 -
1.640 - /* Kill the thread so we can flush everything into the think queue... */
1.641 - KillWorkerThread();
1.642 -
1.643 - /* Run all of the think operations.
1.644 - * Unlike the driver unloading example, we'll let these calls go through,
1.645 - * since a plugin unloading is far more normal.
1.646 - */
1.647 - Queue<IDBThreadOperation *>::iterator iter = m_ThinkQueue.begin();
1.648 - Queue<IDBThreadOperation *> templist;
1.649 - while (iter != m_ThinkQueue.end())
1.650 - {
1.651 - IDBThreadOperation *op = (*iter);
1.652 - if (op->GetOwner() == pToken)
1.653 - {
1.654 - templist.push(op);
1.655 - iter = m_ThinkQueue.erase(iter);
1.656 - } else {
1.657 - iter++;
1.658 - }
1.659 - }
1.660 -
1.661 - for (iter = templist.begin();
1.662 - iter != templist.end();
1.663 - iter++)
1.664 - {
1.665 - IDBThreadOperation *op = (*iter);
1.666 - op->RunThinkPart();
1.667 - op->Destroy();
1.668 - }
1.669 -
1.670 - s_pAddBlock = NULL;
1.671 -}
1.672 -
1.673 -void DBManager::OnPluginUnloaded(IPlugin *plugin)
1.674 -{
1.675 - /* Kill the thread so we can flush everything into the think queue... */
1.676 - KillWorkerThread();
1.677 -
1.678 - /* Mark the plugin as being unloaded so future database calls will ignore threading... */
1.679 - plugin->SetProperty("DisallowDBThreads", NULL);
1.680 -
1.681 - /* Run all of the think operations.
1.682 - * Unlike the driver unloading example, we'll let these calls go through,
1.683 - * since a plugin unloading is far more normal.
1.684 - */
1.685 - Queue<IDBThreadOperation *>::iterator iter = m_ThinkQueue.begin();
1.686 - Queue<IDBThreadOperation *> templist;
1.687 - while (iter != m_ThinkQueue.end())
1.688 - {
1.689 - IDBThreadOperation *op = (*iter);
1.690 - if (op->GetOwner() == plugin->GetIdentity())
1.691 - {
1.692 - templist.push(op);
1.693 - iter = m_ThinkQueue.erase(iter);
1.694 - } else {
1.695 - iter++;
1.696 - }
1.697 - }
1.698 -
1.699 - for (iter = templist.begin();
1.700 - iter != templist.end();
1.701 - iter++)
1.702 - {
1.703 - IDBThreadOperation *op = (*iter);
1.704 - op->RunThinkPart();
1.705 - op->Destroy();
1.706 - }
1.707 -}
1.708 -
1.709 -void DBManager::LockConfig()
1.710 -{
1.711 - m_pConfigLock->Lock();
1.712 -}
1.713 -
1.714 -void DBManager::UnlockConfig()
1.715 -{
1.716 - m_pConfigLock->Unlock();
1.717 -}
1.718 -
1.719 -const char *DBManager::GetDefaultDriverName()
1.720 -{
1.721 - return m_DefDriver.c_str();
1.722 -}