From 97e25c37dece66f32a729e9e644193ee27217248 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Tue, 17 Feb 2009 15:59:51 -0500 Subject: [PATCH] Deprecated Acquire/ReleaseLock from IGameConfigManager, use thread pump in updater. --- core/GameConfigs.cpp | 11 ----- core/GameConfigs.h | 1 - extensions/updater/Updater.cpp | 79 +++++++++++++++++--------------- extensions/updater/Updater.h | 12 +++++ extensions/updater/extension.cpp | 75 ++++++++++++++++++------------ public/IGameConfigs.h | 4 +- 6 files changed, 102 insertions(+), 80 deletions(-) diff --git a/core/GameConfigs.cpp b/core/GameConfigs.cpp index c58aaecb..54d9e665 100644 --- a/core/GameConfigs.cpp +++ b/core/GameConfigs.cpp @@ -762,15 +762,11 @@ bool CGameConfig::EnterFile(const char *file, char *error, size_t maxlength) bShouldBeReadingDefault = true; m_ParseState = PSTATE_NONE; - g_GameConfigs.AcquireLock(); - if ((err=textparsers->ParseSMCFile(m_CurFile, this, &state, error, maxlength)) != SMCError_Okay) { const char *msg; - g_GameConfigs.ReleaseLock(); - msg = textparsers->GetSMCErrorString(err); 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; } - g_GameConfigs.ReleaseLock(); - return true; } @@ -860,8 +854,6 @@ GameConfigManager::~GameConfigManager() void GameConfigManager::OnSourceModStartup(bool late) { - m_FileLock = g_pThreader->MakeMutex(); - LoadGameConfigFile("core.games", &g_pGameConf, NULL, 0); strncopy(g_Game, g_SourceMod.GetGameFolderName(), sizeof(g_Game)); @@ -896,7 +888,6 @@ void GameConfigManager::OnSourceModAllInitialized() void GameConfigManager::OnSourceModAllShutdown() { CloseGameConfigFile(g_pGameConf); - m_FileLock->DestroyThis(); } 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() { - m_FileLock->Lock(); } void GameConfigManager::ReleaseLock() { - m_FileLock->Unlock(); } diff --git a/core/GameConfigs.h b/core/GameConfigs.h index 9fc512f5..162a85f4 100644 --- a/core/GameConfigs.h +++ b/core/GameConfigs.h @@ -120,7 +120,6 @@ public: //SMGlobalClass private: List m_cfgs; Trie *m_pLookup; - IMutex *m_FileLock; public: KTrie m_customHandlers; }; diff --git a/extensions/updater/Updater.cpp b/extensions/updater/Updater.cpp index 5df16414..6e465084 100644 --- a/extensions/updater/Updater.cpp +++ b/extensions/updater/Updater.cpp @@ -43,7 +43,7 @@ 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; } +void UpdateReader::LinkPart(UpdatePart *part) +{ + part->next = NULL; + if (partFirst == NULL) + { + partFirst = part; + partLast = part; + } + else + { + partLast->next = part; + partLast = part; + } +} + void UpdateReader::HandleFile() { MD5 md5; @@ -192,6 +207,12 @@ void UpdateReader::HandleFile() md5.finalize(); 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) { AddUpdateError("Checksums for file \"%s\" do not match:", curfile.c_str()); @@ -199,45 +220,20 @@ void UpdateReader::HandleFile() return; } - char path[PLATFORM_MAX_PATH]; - smutils->BuildPath(Path_SM, path, sizeof(path), "gamedata/%s", curfile.c_str()); - - gameconfs->AcquireLock(); - - 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()); + UpdatePart *part = new UpdatePart; + part->data = (char*)malloc(mdl.GetSize()); + part->file = strdup(curfile.c_str()); + part->length = mdl.GetSize(); + LinkPart(part); } void UpdateReader::HandleFolder(const char *folder) { - char path[PLATFORM_MAX_PATH]; - - smutils->BuildPath(Path_SM, path, sizeof(path), "gamedata/%s", folder); - if (libsys->IsPathDirectory(path)) - { - return; - } - - if (!libsys->CreateFolder(path)) - { - AddUpdateError("Could not create folder: %s", path); - } - else - { - AddUpdateMessage("Created folder \"%s\" from updater", folder); - } + UpdatePart *part = new UpdatePart; + part->data = NULL; + part->length = 0; + part->file = strdup(folder); + LinkPart(part); } static bool md5_file(const char *file, char checksum[33]) @@ -381,3 +377,14 @@ cleanup: delete xfer; delete form; } + +UpdatePart *UpdateReader::DetachParts() +{ + UpdatePart *first; + + first = partFirst; + partFirst = NULL; + partLast = NULL; + + return first; +} diff --git a/extensions/updater/Updater.h b/extensions/updater/Updater.h index 0412f6cd..ce84372e 100644 --- a/extensions/updater/Updater.h +++ b/extensions/updater/Updater.h @@ -37,6 +37,14 @@ #include #include "MemoryDownloader.h" +struct UpdatePart +{ + UpdatePart* next; + char *file; + char *data; + size_t length; +}; + namespace SourceMod { class UpdateReader : @@ -52,9 +60,11 @@ namespace SourceMod SMCResult ReadSMC_LeavingSection(const SMCStates *states); public: void PerformUpdate(); + UpdatePart *DetachParts(); private: void HandleFile(); void HandleFolder(const char *folder); + void LinkPart(UpdatePart *part); private: IWebTransfer *xfer; MemoryDownloader mdl; @@ -63,6 +73,8 @@ namespace SourceMod SourceHook::String curfile; SourceHook::String url; char checksum[33]; + UpdatePart *partFirst; + UpdatePart *partLast; }; } diff --git a/extensions/updater/extension.cpp b/extensions/updater/extension.cpp index 7c2da506..255831cd 100644 --- a/extensions/updater/extension.cpp +++ b/extensions/updater/extension.cpp @@ -45,7 +45,6 @@ SMEXT_LINK(&g_Updater); IWebternet *webternet; static List update_errors; -static List update_messages; static IThreadHandle *update_thread; bool SmUpdater::SDK_OnLoad(char *error, size_t maxlength, bool late) @@ -85,10 +84,6 @@ void SmUpdater::SDK_OnUnload() { iter = update_errors.erase(iter); } - while (iter != update_messages.end()) - { - iter = update_messages.erase(iter); - } } 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; List::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()) { 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 ---"); } - - for (iter = update_messages.begin(); - iter != update_messages.end(); - iter++) - { - str = (*iter); - smutils->LogMessage(myself, "%s", str->c_str()); - } } void SmUpdater::RunThread(IThreadHandle *pHandle) @@ -147,28 +177,13 @@ void SmUpdater::RunThread(IThreadHandle *pHandle) ur.PerformUpdate(); - if (update_errors.size() || update_messages.size()) - { - smutils->AddFrameAction(LogAllMessages, NULL); - } + smutils->AddFrameAction(PumpUpdate, ur.DetachParts()); } 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, ...) { va_list ap; diff --git a/public/IGameConfigs.h b/public/IGameConfigs.h index e9c63e88..be00a1e5 100644 --- a/public/IGameConfigs.h +++ b/public/IGameConfigs.h @@ -163,12 +163,12 @@ namespace SourceMod 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; /** - * @brief Releases the file reading lock. + * @brief Does nothing. */ virtual void ReleaseLock() = 0; };