Deprecated Acquire/ReleaseLock from IGameConfigManager, use thread pump in updater.
authorDavid Anderson <dvander@alliedmods.net>
Tue Feb 17 15:59:51 2009 -0500 (2009-02-17)
changeset 25739e715ee7389e
parent 2572 16a26a23c813
child 2574 d05c7ee81134
Deprecated Acquire/ReleaseLock from IGameConfigManager, use thread pump in updater.
core/GameConfigs.cpp
core/GameConfigs.h
extensions/updater/Updater.cpp
extensions/updater/Updater.h
extensions/updater/extension.cpp
public/IGameConfigs.h
     1.1 --- a/core/GameConfigs.cpp	Tue Feb 17 14:03:20 2009 -0500
     1.2 +++ b/core/GameConfigs.cpp	Tue Feb 17 15:59:51 2009 -0500
     1.3 @@ -762,15 +762,11 @@
     1.4  	bShouldBeReadingDefault = true;
     1.5  	m_ParseState = PSTATE_NONE;
     1.6  
     1.7 -	g_GameConfigs.AcquireLock();
     1.8 -
     1.9  	if ((err=textparsers->ParseSMCFile(m_CurFile, this, &state, error, maxlength))
    1.10  		!= SMCError_Okay)
    1.11  	{
    1.12  		const char *msg;
    1.13  
    1.14 -		g_GameConfigs.ReleaseLock();
    1.15 -
    1.16  		msg = textparsers->GetSMCErrorString(err);
    1.17  
    1.18  		g_Logger.LogError("[SM] Error parsing gameconfig file \"%s\":", m_CurFile);
    1.19 @@ -791,8 +787,6 @@
    1.20  		return false;
    1.21  	}
    1.22  
    1.23 -	g_GameConfigs.ReleaseLock();
    1.24 -
    1.25  	return true;
    1.26  }
    1.27  
    1.28 @@ -860,8 +854,6 @@
    1.29  
    1.30  void GameConfigManager::OnSourceModStartup(bool late)
    1.31  {
    1.32 -	m_FileLock = g_pThreader->MakeMutex();
    1.33 -
    1.34  	LoadGameConfigFile("core.games", &g_pGameConf, NULL, 0);
    1.35  
    1.36  	strncopy(g_Game, g_SourceMod.GetGameFolderName(), sizeof(g_Game));
    1.37 @@ -896,7 +888,6 @@
    1.38  void GameConfigManager::OnSourceModAllShutdown()
    1.39  {
    1.40  	CloseGameConfigFile(g_pGameConf);
    1.41 -	m_FileLock->DestroyThis();
    1.42  }
    1.43  
    1.44  bool GameConfigManager::LoadGameConfigFile(const char *file, IGameConfig **_pConfig, char *error, size_t maxlength)
    1.45 @@ -991,10 +982,8 @@
    1.46  
    1.47  void GameConfigManager::AcquireLock()
    1.48  {
    1.49 -	m_FileLock->Lock();
    1.50  }
    1.51  
    1.52  void GameConfigManager::ReleaseLock()
    1.53  {
    1.54 -	m_FileLock->Unlock();
    1.55  }
     2.1 --- a/core/GameConfigs.h	Tue Feb 17 14:03:20 2009 -0500
     2.2 +++ b/core/GameConfigs.h	Tue Feb 17 15:59:51 2009 -0500
     2.3 @@ -120,7 +120,6 @@
     2.4  private:
     2.5  	List<CGameConfig *> m_cfgs;
     2.6  	Trie *m_pLookup;
     2.7 -	IMutex *m_FileLock;
     2.8  public:
     2.9  	KTrie<ITextListener_SMC *> m_customHandlers;
    2.10  };
     3.1 --- a/extensions/updater/Updater.cpp	Tue Feb 17 14:03:20 2009 -0500
     3.2 +++ b/extensions/updater/Updater.cpp	Tue Feb 17 15:59:51 2009 -0500
     3.3 @@ -43,7 +43,7 @@
     3.4  
     3.5  using namespace SourceMod;
     3.6  
     3.7 -UpdateReader::UpdateReader()
     3.8 +UpdateReader::UpdateReader() : partFirst(NULL), partLast(NULL)
     3.9  {
    3.10  }
    3.11  
    3.12 @@ -174,6 +174,21 @@
    3.13  	return SMCResult_Continue;
    3.14  }
    3.15  
    3.16 +void UpdateReader::LinkPart(UpdatePart *part)
    3.17 +{
    3.18 +	part->next = NULL;
    3.19 +	if (partFirst == NULL)
    3.20 +	{
    3.21 +		partFirst = part;
    3.22 +		partLast = part;
    3.23 +	}
    3.24 +	else
    3.25 +	{
    3.26 +		partLast->next = part;
    3.27 +		partLast = part;
    3.28 +	}
    3.29 +}
    3.30 +
    3.31  void UpdateReader::HandleFile()
    3.32  {
    3.33  	MD5 md5;
    3.34 @@ -192,6 +207,12 @@
    3.35  	md5.finalize();
    3.36  	md5.hex_digest(real_checksum);
    3.37  
    3.38 +	if (mdl.GetSize() == 0)
    3.39 +	{
    3.40 +		AddUpdateError("Zero-length file returned for \"%s\"", curfile.c_str());
    3.41 +		return;
    3.42 +	}
    3.43 +
    3.44  	if (strcasecmp(checksum, real_checksum) != 0)
    3.45  	{
    3.46  		AddUpdateError("Checksums for file \"%s\" do not match:", curfile.c_str());
    3.47 @@ -199,45 +220,20 @@
    3.48  		return;
    3.49  	}
    3.50  
    3.51 -	char path[PLATFORM_MAX_PATH];
    3.52 -	smutils->BuildPath(Path_SM, path, sizeof(path), "gamedata/%s", curfile.c_str());
    3.53 -
    3.54 -	gameconfs->AcquireLock();
    3.55 -	
    3.56 -	FILE *fp = fopen(path, "wt");
    3.57 -	if (fp == NULL)
    3.58 -	{
    3.59 -		gameconfs->ReleaseLock();
    3.60 -		AddUpdateError("Could not open %s for writing", path);
    3.61 -		return;
    3.62 -	}
    3.63 -
    3.64 -	fwrite(mdl.GetBuffer(), 1, mdl.GetSize(), fp);
    3.65 -	fclose(fp);
    3.66 -
    3.67 -	gameconfs->ReleaseLock();
    3.68 -
    3.69 -	AddUpdateMessage("Successfully updated gamedata file \"%s\"", curfile.c_str());
    3.70 +	UpdatePart *part = new UpdatePart;
    3.71 +	part->data = (char*)malloc(mdl.GetSize());
    3.72 +	part->file = strdup(curfile.c_str());
    3.73 +	part->length = mdl.GetSize();
    3.74 +	LinkPart(part);
    3.75  }
    3.76  
    3.77  void UpdateReader::HandleFolder(const char *folder)
    3.78  {
    3.79 -	char path[PLATFORM_MAX_PATH];
    3.80 -
    3.81 -	smutils->BuildPath(Path_SM, path, sizeof(path), "gamedata/%s", folder);
    3.82 -	if (libsys->IsPathDirectory(path))
    3.83 -	{
    3.84 -		return;
    3.85 -	}
    3.86 -
    3.87 -	if (!libsys->CreateFolder(path))
    3.88 -	{
    3.89 -		AddUpdateError("Could not create folder: %s", path);
    3.90 -	}
    3.91 -	else
    3.92 -	{
    3.93 -		AddUpdateMessage("Created folder \"%s\" from updater", folder);
    3.94 -	}
    3.95 +	UpdatePart *part = new UpdatePart;
    3.96 +	part->data = NULL;
    3.97 +	part->length = 0;
    3.98 +	part->file = strdup(folder);
    3.99 +	LinkPart(part);
   3.100  }
   3.101  
   3.102  static bool md5_file(const char *file, char checksum[33])
   3.103 @@ -381,3 +377,14 @@
   3.104  	delete xfer;
   3.105  	delete form;
   3.106  }
   3.107 +
   3.108 +UpdatePart *UpdateReader::DetachParts()
   3.109 +{
   3.110 +	UpdatePart *first;
   3.111 +
   3.112 +	first = partFirst;
   3.113 +	partFirst = NULL;
   3.114 +	partLast = NULL;
   3.115 +
   3.116 +	return first;
   3.117 +}
     4.1 --- a/extensions/updater/Updater.h	Tue Feb 17 14:03:20 2009 -0500
     4.2 +++ b/extensions/updater/Updater.h	Tue Feb 17 15:59:51 2009 -0500
     4.3 @@ -37,6 +37,14 @@
     4.4  #include <sh_string.h>
     4.5  #include "MemoryDownloader.h"
     4.6  
     4.7 +struct UpdatePart
     4.8 +{
     4.9 +	UpdatePart* next;
    4.10 +	char *file;
    4.11 +	char *data;
    4.12 +	size_t length;
    4.13 +};
    4.14 +
    4.15  namespace SourceMod
    4.16  {
    4.17  	class UpdateReader : 
    4.18 @@ -52,9 +60,11 @@
    4.19  		SMCResult ReadSMC_LeavingSection(const SMCStates *states);
    4.20  	public:
    4.21  		void PerformUpdate();
    4.22 +		UpdatePart *DetachParts();
    4.23  	private:
    4.24  		void HandleFile();
    4.25  		void HandleFolder(const char *folder);
    4.26 +		void LinkPart(UpdatePart *part);
    4.27  	private:
    4.28  		IWebTransfer *xfer;
    4.29  		MemoryDownloader mdl;
    4.30 @@ -63,6 +73,8 @@
    4.31  		SourceHook::String curfile;
    4.32  		SourceHook::String url;
    4.33  		char checksum[33];
    4.34 +		UpdatePart *partFirst;
    4.35 +		UpdatePart *partLast;
    4.36  	};
    4.37  }
    4.38  
     5.1 --- a/extensions/updater/extension.cpp	Tue Feb 17 14:03:20 2009 -0500
     5.2 +++ b/extensions/updater/extension.cpp	Tue Feb 17 15:59:51 2009 -0500
     5.3 @@ -45,7 +45,6 @@
     5.4  
     5.5  IWebternet *webternet;
     5.6  static List<String *> update_errors;
     5.7 -static List<String *> update_messages;
     5.8  static IThreadHandle *update_thread;
     5.9  
    5.10  bool SmUpdater::SDK_OnLoad(char *error, size_t maxlength, bool late)
    5.11 @@ -85,10 +84,6 @@
    5.12  	{
    5.13  		iter = update_errors.erase(iter);
    5.14  	}
    5.15 -	while (iter != update_messages.end())
    5.16 -	{
    5.17 -		iter = update_messages.erase(iter);
    5.18 -	}
    5.19  }
    5.20  
    5.21  bool SmUpdater::QueryInterfaceDrop(SourceMod::SMInterface *pInterface)
    5.22 @@ -112,11 +107,54 @@
    5.23  	}
    5.24  }
    5.25  
    5.26 -static void LogAllMessages(void *data)
    5.27 +static void PumpUpdate(void *data)
    5.28  {
    5.29  	String *str;
    5.30  	List<String *>::iterator iter;
    5.31  
    5.32 +	char path[PLATFORM_MAX_PATH];
    5.33 +	UpdatePart *temp;
    5.34 +	UpdatePart *part = (UpdatePart*)data;
    5.35 +	while (part != NULL)
    5.36 +	{
    5.37 +		if (part->data == NULL)
    5.38 +		{
    5.39 +			smutils->BuildPath(Path_SM, path, sizeof(path), "gamedata/%s", part->file);
    5.40 +			if (libsys->IsPathDirectory(path))
    5.41 +			{
    5.42 +				continue;
    5.43 +			}
    5.44 +			if (!libsys->CreateFolder(path))
    5.45 +			{
    5.46 +				AddUpdateError("Could not create folder: %s", path);
    5.47 +			}
    5.48 +			else
    5.49 +			{
    5.50 +				smutils->LogMessage(myself, "Created folder \"%s\" from updater", path);
    5.51 +			}
    5.52 +		}
    5.53 +		else
    5.54 +		{
    5.55 +			smutils->BuildPath(Path_SM, path, sizeof(path), "gamedata/%s", part->file);
    5.56 +			FILE *fp = fopen(path, "wt");
    5.57 +			if (fp == NULL)
    5.58 +			{
    5.59 +				AddUpdateError("Could not open %s for writing", path);
    5.60 +				return;
    5.61 +			}
    5.62 +			fwrite(part->data, 1, part->length, fp);
    5.63 +			fclose(fp);
    5.64 +			smutils->LogMessage(myself,
    5.65 +				"Successfully updated gamedata file \"%s\"",
    5.66 +				part->file);
    5.67 +		}
    5.68 +		temp = part->next;
    5.69 +		free(part->data);
    5.70 +		free(part->file);
    5.71 +		delete part;
    5.72 +		part = temp;
    5.73 +	}
    5.74 +
    5.75  	if (update_errors.size())
    5.76  	{
    5.77  		smutils->LogError(myself, "--- BEGIN ERRORS FROM AUTOMATIC UPDATER ---");
    5.78 @@ -131,14 +169,6 @@
    5.79  
    5.80  		smutils->LogError(myself, "--- END ERRORS FROM AUTOMATIC UPDATER ---");
    5.81  	}
    5.82 -
    5.83 -	for (iter = update_messages.begin();
    5.84 -		 iter != update_messages.end();
    5.85 -		 iter++)
    5.86 -	{
    5.87 -		str = (*iter);
    5.88 -		smutils->LogMessage(myself, "%s", str->c_str());
    5.89 -	}
    5.90  }
    5.91  
    5.92  void SmUpdater::RunThread(IThreadHandle *pHandle)
    5.93 @@ -147,28 +177,13 @@
    5.94  
    5.95  	ur.PerformUpdate();
    5.96  
    5.97 -	if (update_errors.size() || update_messages.size())
    5.98 -	{
    5.99 -		smutils->AddFrameAction(LogAllMessages, NULL);
   5.100 -	}
   5.101 +	smutils->AddFrameAction(PumpUpdate, ur.DetachParts());
   5.102  }
   5.103  
   5.104  void SmUpdater::OnTerminate(IThreadHandle *pHandle, bool cancel)
   5.105  {
   5.106  }
   5.107  
   5.108 -void AddUpdateMessage(const char *fmt, ...)
   5.109 -{
   5.110 -	va_list ap;
   5.111 -	char buffer[2048];
   5.112 -
   5.113 -	va_start(ap, fmt);
   5.114 -	smutils->FormatArgs(buffer, sizeof(buffer), fmt, ap);
   5.115 -	va_end(ap);
   5.116 -
   5.117 -	update_messages.push_back(new String(buffer));
   5.118 -}
   5.119 -
   5.120  void AddUpdateError(const char *fmt, ...)
   5.121  {
   5.122  	va_list ap;
     6.1 --- a/public/IGameConfigs.h	Tue Feb 17 14:03:20 2009 -0500
     6.2 +++ b/public/IGameConfigs.h	Tue Feb 17 15:59:51 2009 -0500
     6.3 @@ -163,12 +163,12 @@
     6.4  		virtual void RemoveUserConfigHook(const char *sectionname, ITextListener_SMC *listener) =0;
     6.5  
     6.6  		/**
     6.7 -		 * @brief Acquires a file reading lock on the gamedata system.  
     6.8 +		 * @brief Does nothing.
     6.9  		 */
    6.10  		virtual void AcquireLock() = 0;
    6.11  
    6.12  		/**
    6.13 -		 * @brief Releases the file reading lock.
    6.14 +		 * @brief Does nothing.
    6.15  		 */
    6.16  		virtual void ReleaseLock() = 0;
    6.17  	};