[AssetHandler] Use thread_local declaration instead of mutex

This commit is contained in:
momo5502 2016-12-21 17:08:15 +01:00
parent caa9787507
commit fac7f0ef4c
2 changed files with 7 additions and 39 deletions

View File

@ -2,8 +2,7 @@
namespace Components namespace Components
{ {
std::recursive_mutex AssetHandler::BypassMutex; thread_local bool AssetHandler::BypassState;
std::vector<std::thread::id> AssetHandler::BypassThreads;
std::map<Game::XAssetType, AssetHandler::IAsset*> AssetHandler::AssetInterfaces; std::map<Game::XAssetType, AssetHandler::IAsset*> AssetHandler::AssetInterfaces;
std::map<Game::XAssetType, wink::slot<AssetHandler::Callback>> AssetHandler::TypeCallbacks; std::map<Game::XAssetType, wink::slot<AssetHandler::Callback>> AssetHandler::TypeCallbacks;
wink::signal<wink::slot<AssetHandler::RestrictCallback>> AssetHandler::RestrictSignal; wink::signal<wink::slot<AssetHandler::RestrictCallback>> AssetHandler::RestrictSignal;
@ -56,7 +55,7 @@ namespace Components
if (filename) if (filename)
{ {
// Allow call DB_FindXAssetHeader within the hook // Allow call DB_FindXAssetHeader within the hook
AssetHandler::SetThreadBypass(); AssetHandler::BypassState = true;
if (AssetHandler::TypeCallbacks.find(type) != AssetHandler::TypeCallbacks.end()) if (AssetHandler::TypeCallbacks.find(type) != AssetHandler::TypeCallbacks.end())
{ {
@ -64,7 +63,7 @@ namespace Components
} }
// Disallow calling DB_FindXAssetHeader ;) // Disallow calling DB_FindXAssetHeader ;)
AssetHandler::ClearThreadBypass(); AssetHandler::BypassState = false;
} }
return header; return header;
@ -72,33 +71,7 @@ namespace Components
int AssetHandler::HasThreadBypass() int AssetHandler::HasThreadBypass()
{ {
std::lock_guard<std::recursive_mutex> _(AssetHandler::BypassMutex); return AssetHandler::BypassState & 1;
return (std::find(AssetHandler::BypassThreads.begin(), AssetHandler::BypassThreads.end(), std::this_thread::get_id()) != AssetHandler::BypassThreads.end()) & 1;
}
void AssetHandler::SetThreadBypass()
{
std::lock_guard<std::recursive_mutex> _(AssetHandler::BypassMutex);
if (!AssetHandler::HasThreadBypass())
{
AssetHandler::BypassThreads.push_back(std::this_thread::get_id());
}
}
void AssetHandler::ClearThreadBypass()
{
std::lock_guard<std::recursive_mutex> _(AssetHandler::BypassMutex);
while (AssetHandler::HasThreadBypass())
{
auto i = std::find(AssetHandler::BypassThreads.begin(), AssetHandler::BypassThreads.end(), std::this_thread::get_id());
if (i != AssetHandler::BypassThreads.end())
{
AssetHandler::BypassThreads.erase(i);
}
}
} }
__declspec(naked) void AssetHandler::FindAssetStub() __declspec(naked) void AssetHandler::FindAssetStub()
@ -339,13 +312,11 @@ namespace Components
Game::XAssetHeader AssetHandler::FindOriginalAsset(Game::XAssetType type, const char* filename) Game::XAssetHeader AssetHandler::FindOriginalAsset(Game::XAssetType type, const char* filename)
{ {
std::lock_guard<std::recursive_mutex> _(AssetHandler::BypassMutex);
int originalState = AssetHandler::HasThreadBypass(); int originalState = AssetHandler::HasThreadBypass();
AssetHandler::SetThreadBypass(); AssetHandler::BypassState = true;
Game::XAssetHeader header = Game::DB_FindXAssetHeader(type, filename); Game::XAssetHeader header = Game::DB_FindXAssetHeader(type, filename);
if (!originalState) AssetHandler::ClearThreadBypass(); if (!originalState) AssetHandler::BypassState = false;
return header; return header;
} }

View File

@ -40,8 +40,7 @@ namespace Components
static void StoreTemporaryAsset(Game::XAssetType type, Game::XAssetHeader asset); static void StoreTemporaryAsset(Game::XAssetType type, Game::XAssetHeader asset);
private: private:
static std::recursive_mutex BypassMutex; static thread_local bool BypassState;
static std::vector<std::thread::id> BypassThreads;
static std::map<std::string, Game::XAssetHeader> TemporaryAssets[Game::XAssetType::ASSET_TYPE_COUNT]; static std::map<std::string, Game::XAssetHeader> TemporaryAssets[Game::XAssetType::ASSET_TYPE_COUNT];
@ -68,8 +67,6 @@ namespace Components
static void ModifyAsset(Game::XAssetType type, Game::XAssetHeader asset, std::string name); static void ModifyAsset(Game::XAssetType type, Game::XAssetHeader asset, std::string name);
static int HasThreadBypass(); static int HasThreadBypass();
static void SetThreadBypass();
static void ClearThreadBypass();
}; };
} }