Deprecated Acquire/ReleaseLock from IGameConfigManager, use thread pump in updater.

This commit is contained in:
David Anderson 2009-02-17 15:59:51 -05:00
parent 16033c1307
commit 97e25c37de
6 changed files with 102 additions and 80 deletions

View File

@ -762,15 +762,11 @@ bool CGameConfig::EnterFile(const char *file, char *error, size_t maxlength)
bShouldBeReadingDefault = true; bShouldBeReadingDefault = true;
m_ParseState = PSTATE_NONE; m_ParseState = PSTATE_NONE;
g_GameConfigs.AcquireLock();
if ((err=textparsers->ParseSMCFile(m_CurFile, this, &state, error, maxlength)) if ((err=textparsers->ParseSMCFile(m_CurFile, this, &state, error, maxlength))
!= SMCError_Okay) != SMCError_Okay)
{ {
const char *msg; const char *msg;
g_GameConfigs.ReleaseLock();
msg = textparsers->GetSMCErrorString(err); msg = textparsers->GetSMCErrorString(err);
g_Logger.LogError("[SM] Error parsing gameconfig file \"%s\":", m_CurFile); g_Logger.LogError("[SM] Error parsing gameconfig file \"%s\":", m_CurFile);
@ -791,8 +787,6 @@ bool CGameConfig::EnterFile(const char *file, char *error, size_t maxlength)
return false; return false;
} }
g_GameConfigs.ReleaseLock();
return true; return true;
} }
@ -860,8 +854,6 @@ GameConfigManager::~GameConfigManager()
void GameConfigManager::OnSourceModStartup(bool late) void GameConfigManager::OnSourceModStartup(bool late)
{ {
m_FileLock = g_pThreader->MakeMutex();
LoadGameConfigFile("core.games", &g_pGameConf, NULL, 0); LoadGameConfigFile("core.games", &g_pGameConf, NULL, 0);
strncopy(g_Game, g_SourceMod.GetGameFolderName(), sizeof(g_Game)); strncopy(g_Game, g_SourceMod.GetGameFolderName(), sizeof(g_Game));
@ -896,7 +888,6 @@ void GameConfigManager::OnSourceModAllInitialized()
void GameConfigManager::OnSourceModAllShutdown() void GameConfigManager::OnSourceModAllShutdown()
{ {
CloseGameConfigFile(g_pGameConf); CloseGameConfigFile(g_pGameConf);
m_FileLock->DestroyThis();
} }
bool GameConfigManager::LoadGameConfigFile(const char *file, IGameConfig **_pConfig, char *error, size_t maxlength) bool GameConfigManager::LoadGameConfigFile(const char *file, IGameConfig **_pConfig, char *error, size_t maxlength)
@ -991,10 +982,8 @@ void GameConfigManager::RemoveUserConfigHook(const char *sectionname, ITextListe
void GameConfigManager::AcquireLock() void GameConfigManager::AcquireLock()
{ {
m_FileLock->Lock();
} }
void GameConfigManager::ReleaseLock() void GameConfigManager::ReleaseLock()
{ {
m_FileLock->Unlock();
} }

View File

@ -120,7 +120,6 @@ public: //SMGlobalClass
private: private:
List<CGameConfig *> m_cfgs; List<CGameConfig *> m_cfgs;
Trie *m_pLookup; Trie *m_pLookup;
IMutex *m_FileLock;
public: public:
KTrie<ITextListener_SMC *> m_customHandlers; KTrie<ITextListener_SMC *> m_customHandlers;
}; };

View File

@ -43,7 +43,7 @@
using namespace SourceMod; using namespace SourceMod;
UpdateReader::UpdateReader() UpdateReader::UpdateReader() : partFirst(NULL), partLast(NULL)
{ {
} }
@ -174,6 +174,21 @@ SMCResult UpdateReader::ReadSMC_LeavingSection(const SMCStates *states)
return SMCResult_Continue; return SMCResult_Continue;
} }
void UpdateReader::LinkPart(UpdatePart *part)
{
part->next = NULL;
if (partFirst == NULL)
{
partFirst = part;
partLast = part;
}
else
{
partLast->next = part;
partLast = part;
}
}
void UpdateReader::HandleFile() void UpdateReader::HandleFile()
{ {
MD5 md5; MD5 md5;
@ -192,6 +207,12 @@ void UpdateReader::HandleFile()
md5.finalize(); md5.finalize();
md5.hex_digest(real_checksum); md5.hex_digest(real_checksum);
if (mdl.GetSize() == 0)
{
AddUpdateError("Zero-length file returned for \"%s\"", curfile.c_str());
return;
}
if (strcasecmp(checksum, real_checksum) != 0) if (strcasecmp(checksum, real_checksum) != 0)
{ {
AddUpdateError("Checksums for file \"%s\" do not match:", curfile.c_str()); AddUpdateError("Checksums for file \"%s\" do not match:", curfile.c_str());
@ -199,45 +220,20 @@ void UpdateReader::HandleFile()
return; return;
} }
char path[PLATFORM_MAX_PATH]; UpdatePart *part = new UpdatePart;
smutils->BuildPath(Path_SM, path, sizeof(path), "gamedata/%s", curfile.c_str()); part->data = (char*)malloc(mdl.GetSize());
part->file = strdup(curfile.c_str());
gameconfs->AcquireLock(); part->length = mdl.GetSize();
LinkPart(part);
FILE *fp = fopen(path, "wt");
if (fp == NULL)
{
gameconfs->ReleaseLock();
AddUpdateError("Could not open %s for writing", path);
return;
}
fwrite(mdl.GetBuffer(), 1, mdl.GetSize(), fp);
fclose(fp);
gameconfs->ReleaseLock();
AddUpdateMessage("Successfully updated gamedata file \"%s\"", curfile.c_str());
} }
void UpdateReader::HandleFolder(const char *folder) void UpdateReader::HandleFolder(const char *folder)
{ {
char path[PLATFORM_MAX_PATH]; UpdatePart *part = new UpdatePart;
part->data = NULL;
smutils->BuildPath(Path_SM, path, sizeof(path), "gamedata/%s", folder); part->length = 0;
if (libsys->IsPathDirectory(path)) part->file = strdup(folder);
{ LinkPart(part);
return;
}
if (!libsys->CreateFolder(path))
{
AddUpdateError("Could not create folder: %s", path);
}
else
{
AddUpdateMessage("Created folder \"%s\" from updater", folder);
}
} }
static bool md5_file(const char *file, char checksum[33]) static bool md5_file(const char *file, char checksum[33])
@ -381,3 +377,14 @@ cleanup:
delete xfer; delete xfer;
delete form; delete form;
} }
UpdatePart *UpdateReader::DetachParts()
{
UpdatePart *first;
first = partFirst;
partFirst = NULL;
partLast = NULL;
return first;
}

View File

@ -37,6 +37,14 @@
#include <sh_string.h> #include <sh_string.h>
#include "MemoryDownloader.h" #include "MemoryDownloader.h"
struct UpdatePart
{
UpdatePart* next;
char *file;
char *data;
size_t length;
};
namespace SourceMod namespace SourceMod
{ {
class UpdateReader : class UpdateReader :
@ -52,9 +60,11 @@ namespace SourceMod
SMCResult ReadSMC_LeavingSection(const SMCStates *states); SMCResult ReadSMC_LeavingSection(const SMCStates *states);
public: public:
void PerformUpdate(); void PerformUpdate();
UpdatePart *DetachParts();
private: private:
void HandleFile(); void HandleFile();
void HandleFolder(const char *folder); void HandleFolder(const char *folder);
void LinkPart(UpdatePart *part);
private: private:
IWebTransfer *xfer; IWebTransfer *xfer;
MemoryDownloader mdl; MemoryDownloader mdl;
@ -63,6 +73,8 @@ namespace SourceMod
SourceHook::String curfile; SourceHook::String curfile;
SourceHook::String url; SourceHook::String url;
char checksum[33]; char checksum[33];
UpdatePart *partFirst;
UpdatePart *partLast;
}; };
} }

View File

@ -45,7 +45,6 @@ SMEXT_LINK(&g_Updater);
IWebternet *webternet; IWebternet *webternet;
static List<String *> update_errors; static List<String *> update_errors;
static List<String *> update_messages;
static IThreadHandle *update_thread; static IThreadHandle *update_thread;
bool SmUpdater::SDK_OnLoad(char *error, size_t maxlength, bool late) bool SmUpdater::SDK_OnLoad(char *error, size_t maxlength, bool late)
@ -85,10 +84,6 @@ void SmUpdater::SDK_OnUnload()
{ {
iter = update_errors.erase(iter); iter = update_errors.erase(iter);
} }
while (iter != update_messages.end())
{
iter = update_messages.erase(iter);
}
} }
bool SmUpdater::QueryInterfaceDrop(SourceMod::SMInterface *pInterface) bool SmUpdater::QueryInterfaceDrop(SourceMod::SMInterface *pInterface)
@ -112,11 +107,54 @@ void SmUpdater::NotifyInterfaceDrop(SMInterface *pInterface)
} }
} }
static void LogAllMessages(void *data) static void PumpUpdate(void *data)
{ {
String *str; String *str;
List<String *>::iterator iter; List<String *>::iterator iter;
char path[PLATFORM_MAX_PATH];
UpdatePart *temp;
UpdatePart *part = (UpdatePart*)data;
while (part != NULL)
{
if (part->data == NULL)
{
smutils->BuildPath(Path_SM, path, sizeof(path), "gamedata/%s", part->file);
if (libsys->IsPathDirectory(path))
{
continue;
}
if (!libsys->CreateFolder(path))
{
AddUpdateError("Could not create folder: %s", path);
}
else
{
smutils->LogMessage(myself, "Created folder \"%s\" from updater", path);
}
}
else
{
smutils->BuildPath(Path_SM, path, sizeof(path), "gamedata/%s", part->file);
FILE *fp = fopen(path, "wt");
if (fp == NULL)
{
AddUpdateError("Could not open %s for writing", path);
return;
}
fwrite(part->data, 1, part->length, fp);
fclose(fp);
smutils->LogMessage(myself,
"Successfully updated gamedata file \"%s\"",
part->file);
}
temp = part->next;
free(part->data);
free(part->file);
delete part;
part = temp;
}
if (update_errors.size()) if (update_errors.size())
{ {
smutils->LogError(myself, "--- BEGIN ERRORS FROM AUTOMATIC UPDATER ---"); smutils->LogError(myself, "--- BEGIN ERRORS FROM AUTOMATIC UPDATER ---");
@ -131,14 +169,6 @@ static void LogAllMessages(void *data)
smutils->LogError(myself, "--- END ERRORS FROM AUTOMATIC UPDATER ---"); smutils->LogError(myself, "--- END ERRORS FROM AUTOMATIC UPDATER ---");
} }
for (iter = update_messages.begin();
iter != update_messages.end();
iter++)
{
str = (*iter);
smutils->LogMessage(myself, "%s", str->c_str());
}
} }
void SmUpdater::RunThread(IThreadHandle *pHandle) void SmUpdater::RunThread(IThreadHandle *pHandle)
@ -147,28 +177,13 @@ void SmUpdater::RunThread(IThreadHandle *pHandle)
ur.PerformUpdate(); ur.PerformUpdate();
if (update_errors.size() || update_messages.size()) smutils->AddFrameAction(PumpUpdate, ur.DetachParts());
{
smutils->AddFrameAction(LogAllMessages, NULL);
}
} }
void SmUpdater::OnTerminate(IThreadHandle *pHandle, bool cancel) void SmUpdater::OnTerminate(IThreadHandle *pHandle, bool cancel)
{ {
} }
void AddUpdateMessage(const char *fmt, ...)
{
va_list ap;
char buffer[2048];
va_start(ap, fmt);
smutils->FormatArgs(buffer, sizeof(buffer), fmt, ap);
va_end(ap);
update_messages.push_back(new String(buffer));
}
void AddUpdateError(const char *fmt, ...) void AddUpdateError(const char *fmt, ...)
{ {
va_list ap; va_list ap;

View File

@ -163,12 +163,12 @@ namespace SourceMod
virtual void RemoveUserConfigHook(const char *sectionname, ITextListener_SMC *listener) =0; virtual void RemoveUserConfigHook(const char *sectionname, ITextListener_SMC *listener) =0;
/** /**
* @brief Acquires a file reading lock on the gamedata system. * @brief Does nothing.
*/ */
virtual void AcquireLock() = 0; virtual void AcquireLock() = 0;
/** /**
* @brief Releases the file reading lock. * @brief Does nothing.
*/ */
virtual void ReleaseLock() = 0; virtual void ReleaseLock() = 0;
}; };