Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove DB Configuration Locking #791

Merged
merged 7 commits into from Jun 19, 2018
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions core/logic/AMBuilder
Expand Up @@ -84,6 +84,7 @@ for arch in SM.archs:
'frame_tasks.cpp',
'smn_halflife.cpp',
'FrameIterator.cpp',
'DatabaseConfBuilder.cpp',
]

if arch == 'x64':
Expand Down
216 changes: 25 additions & 191 deletions core/logic/Database.cpp
Expand Up @@ -47,8 +47,6 @@ static bool s_OneTimeThreaderErrorMsg = false;

DBManager::DBManager()
: m_Terminate(false),
m_ParseLevel(0),
m_ParseState(0),
m_pDefault(NULL)
{
}
Expand All @@ -72,31 +70,16 @@ void DBManager::OnSourceModAllInitialized()
g_ShareSys.AddInterface(NULL, this);

g_pSM->BuildPath(Path_SM, m_Filename, sizeof(m_Filename), "configs/databases.cfg");

m_Builder.SetPath(m_Filename);

g_PluginSys.AddPluginsListener(this);

g_pSM->AddGameFrameHook(&FrameHook);
}

void DBManager::OnSourceModLevelChange(const char *mapName)
{
SMCError err;
SMCStates states = {0, 0};

/* We lock and don't give up the lock until we're done.
* This way the thread's search won't be searching through a
* potentially empty/corrupt list, which would be very bad.
*/
ke::AutoLock lock(&m_ConfigLock);
if ((err = textparsers->ParseFile_SMC(m_Filename, this, &states)) != SMCError_Okay)
{
logger->LogError("[SM] Detected parse error(s) in file \"%s\"", m_Filename);
if (err != SMCError_Custom)
{
const char *txt = textparsers->GetSMCErrorString(err);
logger->LogError("[SM] Line %d: %s", states.line, txt);
}
}
m_Builder.StartParse();
}

void DBManager::OnSourceModShutdown()
Expand All @@ -106,7 +89,6 @@ void DBManager::OnSourceModShutdown()
g_PluginSys.RemovePluginsListener(this);
g_HandleSys.RemoveType(m_DatabaseType, g_pCoreIdent);
g_HandleSys.RemoveType(m_DriverType, g_pCoreIdent);
ClearConfigs();
}

unsigned int DBManager::GetInterfaceVersion()
Expand Down Expand Up @@ -134,136 +116,10 @@ void DBManager::OnHandleDestroy(HandleType_t type, void *object)
}
}

void DBManager::ReadSMC_ParseStart()
{
ClearConfigs();
m_ParseLevel = 0;
m_ParseState = DBPARSE_LEVEL_NONE;
m_DefDriver.clear();
}

void DBManager::ClearConfigs()
{
List<ConfDbInfo *>::iterator iter;
for (iter=m_confs.begin(); iter!=m_confs.end(); iter++)
delete (*iter);
m_confs.clear();
}

ConfDbInfo s_CurInfo;
SMCResult DBManager::ReadSMC_NewSection(const SMCStates *states, const char *name)
{
if (m_ParseLevel)
{
m_ParseLevel++;
return SMCResult_Continue;
}

if (m_ParseState == DBPARSE_LEVEL_NONE)
{
if (strcmp(name, "Databases") == 0)
{
m_ParseState = DBPARSE_LEVEL_MAIN;
} else {
m_ParseLevel++;
}
} else if (m_ParseState == DBPARSE_LEVEL_MAIN) {
s_CurInfo = ConfDbInfo();
s_CurInfo.name = name;
m_ParseState = DBPARSE_LEVEL_DATABASE;
} else if (m_ParseState == DBPARSE_LEVEL_DATABASE) {
m_ParseLevel++;
}

return SMCResult_Continue;
}

SMCResult DBManager::ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
{
if (m_ParseLevel)
{
return SMCResult_Continue;
}

if (m_ParseState == DBPARSE_LEVEL_MAIN)
{
if (strcmp(key, "driver_default") == 0)
{
m_DefDriver.assign(value);
}
} else if (m_ParseState == DBPARSE_LEVEL_DATABASE) {
if (strcmp(key, "driver") == 0)
{
if (strcmp(value, "default") != 0)
{
s_CurInfo.driver = value;
}
} else if (strcmp(key, "database") == 0) {
s_CurInfo.database = value;
} else if (strcmp(key, "host") == 0) {
s_CurInfo.host = value;
} else if (strcmp(key, "user") == 0) {
s_CurInfo.user = value;
} else if (strcmp(key, "pass") == 0) {
s_CurInfo.pass = value;
} else if (strcmp(key, "timeout") == 0) {
s_CurInfo.info.maxTimeout = atoi(value);
} else if (strcmp(key, "port") == 0) {
s_CurInfo.info.port = atoi(value);
}
}

return SMCResult_Continue;
}

SMCResult DBManager::ReadSMC_LeavingSection(const SMCStates *states)
{
if (m_ParseLevel)
{
m_ParseLevel--;
return SMCResult_Continue;
}

if (m_ParseState == DBPARSE_LEVEL_DATABASE)
{
ConfDbInfo *cdb = new ConfDbInfo();

cdb->name = s_CurInfo.name;
cdb->driver = s_CurInfo.driver;
cdb->host = s_CurInfo.host;
cdb->user = s_CurInfo.user;
cdb->pass = s_CurInfo.pass;
cdb->database = s_CurInfo.database;
cdb->realDriver = s_CurInfo.realDriver;
cdb->info.maxTimeout = s_CurInfo.info.maxTimeout;
cdb->info.port = s_CurInfo.info.port;

cdb->info.driver = cdb->driver.c_str();
cdb->info.database = cdb->database.c_str();
cdb->info.host = cdb->host.c_str();
cdb->info.user = cdb->user.c_str();
cdb->info.pass = cdb->pass.c_str();

/* Save it.. */
m_confs.push_back(cdb);

/* Go up one level */
m_ParseState = DBPARSE_LEVEL_MAIN;
} else if (m_ParseState == DBPARSE_LEVEL_MAIN) {
m_ParseState = DBPARSE_LEVEL_NONE;
return SMCResult_Halt;
}

return SMCResult_Continue;
}

void DBManager::ReadSMC_ParseEnd(bool halted, bool failed)
{
}

bool DBManager::Connect(const char *name, IDBDriver **pdr, IDatabase **pdb, bool persistent, char *error, size_t maxlength)
{
ConfDbInfo *pInfo = GetDatabaseConf(name);
ConfDbInfoList *list = m_Builder.GetConfigList();
ConfDbInfo *pInfo = list->GetDatabaseConf(name);

if (!pInfo)
{
Expand All @@ -282,11 +138,12 @@ bool DBManager::Connect(const char *name, IDBDriver **pdr, IDatabase **pdb, bool
/* Try to assign a real driver pointer */
if (pInfo->info.driver[0] == '\0')
{
if (!m_pDefault && m_DefDriver.size() > 0)
ke::AString defaultDriver = list->GetDefaultDriver();
if (!m_pDefault && defaultDriver.length() > 0)
{
m_pDefault = FindOrLoadDriver(m_DefDriver.c_str());
m_pDefault = FindOrLoadDriver(defaultDriver.chars());
}
dname = m_DefDriver.size() ? m_DefDriver.c_str() : "default";
dname = defaultDriver.length() ? defaultDriver.chars() : "default";
pInfo->realDriver = m_pDefault;
} else {
pInfo->realDriver = FindOrLoadDriver(pInfo->info.driver);
Expand All @@ -310,7 +167,6 @@ bool DBManager::Connect(const char *name, IDBDriver **pdr, IDatabase **pdb, bool
*pdb = NULL;

g_pSM->Format(error, maxlength, "Driver \"%s\" not found", dname);

return false;
}

Expand All @@ -323,7 +179,7 @@ void DBManager::AddDriver(IDBDriver *pDriver)
*/
KillWorkerThread();

m_drivers.push_back(pDriver);
m_drivers.push_back(pDriver);
}

void DBManager::RemoveDriver(IDBDriver *pDriver)
Expand All @@ -343,17 +199,17 @@ void DBManager::RemoveDriver(IDBDriver *pDriver)
}
}

/* Make sure NOTHING references this! */
List<ConfDbInfo *>::iterator iter;
for (iter=m_confs.begin(); iter!=m_confs.end(); iter++)
ConfDbInfoList *list = m_Builder.GetConfigList();
for (size_t i = 0; i < list->length(); i++)
{
ConfDbInfo &db = *(*iter);
if (db.realDriver == pDriver)
ConfDbInfo *current = list->at(i);
Headline marked this conversation as resolved.
Show resolved Hide resolved
if (current->realDriver == pDriver)
{
db.realDriver = NULL;
current->realDriver = NULL;
}
}


/* Someone unloaded the default driver? Silly.. */
if (pDriver == m_pDefault)
{
Expand Down Expand Up @@ -389,9 +245,11 @@ void DBManager::RemoveDriver(IDBDriver *pDriver)

IDBDriver *DBManager::GetDefaultDriver()
{
if (!m_pDefault && m_DefDriver.size() > 0)
ConfDbInfoList *list = m_Builder.GetConfigList();
ke::AString defaultDriver = list->GetDefaultDriver();
if (!m_pDefault && defaultDriver.length() > 0)
{
m_pDefault = FindOrLoadDriver(m_DefDriver.c_str());
m_pDefault = FindOrLoadDriver(defaultDriver.chars());
}

return m_pDefault;
Expand Down Expand Up @@ -454,7 +312,8 @@ IDBDriver *DBManager::GetDriver(unsigned int index)

const DatabaseInfo *DBManager::FindDatabaseConf(const char *name)
{
ConfDbInfo *info = GetDatabaseConf(name);
ConfDbInfoList *list = m_Builder.GetConfigList();
ConfDbInfo *info = list->GetDatabaseConf(name);
if (!info)
{
return NULL;
Expand All @@ -463,22 +322,6 @@ const DatabaseInfo *DBManager::FindDatabaseConf(const char *name)
return &info->info;
}

ConfDbInfo *DBManager::GetDatabaseConf(const char *name)
{
List<ConfDbInfo *>::iterator iter;

for (iter=m_confs.begin(); iter!=m_confs.end(); iter++)
{
ConfDbInfo &conf = *(*iter);
if (conf.name == name)
{
return &conf;
}
}

return NULL;
}

IDBDriver *DBManager::FindOrLoadDriver(const char *name)
{
size_t last_size = m_drivers.size();
Expand Down Expand Up @@ -729,19 +572,10 @@ void DBManager::OnPluginWillUnload(IPlugin *plugin)
}
}

void DBManager::LockConfig()
{
m_ConfigLock.Lock();
}

void DBManager::UnlockConfig()
{
m_ConfigLock.Unlock();
}

const char *DBManager::GetDefaultDriverName()
ke::AString DBManager::GetDefaultDriverName()
{
return m_DefDriver.c_str();
ConfDbInfoList *list = m_Builder.GetConfigList();
return list->GetDefaultDriver();
}

void DBManager::AddDependency(IExtension *myself, IDBDriver *driver)
Expand Down