diff options
author | Shauren <shauren.trinity@gmail.com> | 2021-01-17 14:30:36 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2022-10-04 00:19:38 +0200 |
commit | 0be72f68c33617d78a4139f3e667b03d0a22a435 (patch) | |
tree | 66f166bbd6420202bf473cb999f4c7ac6a358662 /src | |
parent | 4cbaaa343543e0fde5d90b87f762804997f1dbac (diff) |
Core/Instances: Sprinkle some thread safety on InstanceLockMgr
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Instances/InstanceLockMgr.cpp | 13 | ||||
-rw-r--r-- | src/server/game/Instances/InstanceLockMgr.h | 3 |
2 files changed, 14 insertions, 2 deletions
diff --git a/src/server/game/Instances/InstanceLockMgr.cpp b/src/server/game/Instances/InstanceLockMgr.cpp index b1c645f46e9..1e2eb22cbe6 100644 --- a/src/server/game/Instances/InstanceLockMgr.cpp +++ b/src/server/game/Instances/InstanceLockMgr.cpp @@ -215,6 +215,8 @@ InstanceLock* InstanceLockMgr::FindActiveInstanceLock(ObjectGuid const& playerGu InstanceLock* InstanceLockMgr::FindActiveInstanceLock(ObjectGuid const& playerGuid, MapDb2Entries const& entries, bool ignoreTemporary, bool ignoreExpired) const { + std::shared_lock<std::shared_mutex> guard(_locksMutex); + InstanceLock* lock = FindInstanceLock(_instanceLocksByPlayer, playerGuid, entries); // Ignore expired and not extended locks @@ -227,6 +229,7 @@ InstanceLock* InstanceLockMgr::FindActiveInstanceLock(ObjectGuid const& playerGu return FindInstanceLock(_temporaryInstanceLocksByPlayer, playerGuid, entries); } +// used in world update thread (THREADUNSAFE packets) - no locking neccessary std::vector<InstanceLock const*> InstanceLockMgr::GetInstanceLocksForPlayer(ObjectGuid const& playerGuid) const { std::vector<InstanceLock const*> locks; @@ -241,6 +244,7 @@ std::vector<InstanceLock const*> InstanceLockMgr::GetInstanceLocksForPlayer(Obje return locks; } +// used in world update thread (cross map teleportation) - no locking neccessary InstanceLock* InstanceLockMgr::CreateInstanceLockForNewInstance(ObjectGuid const& playerGuid, MapDb2Entries const& entries, uint32 instanceId) { if (!entries.MapDifficulty->HasResetSchedule()) @@ -272,6 +276,8 @@ InstanceLock* InstanceLockMgr::UpdateInstanceLockForPlayer(CharacterDatabaseTran InstanceLock* instanceLock = FindActiveInstanceLock(playerGuid, entries, true, true); if (!instanceLock) { + std::unique_lock<std::shared_mutex> guard(_locksMutex); + // Move lock from temporary storage if it exists there // This is to avoid destroying expired locks before any boss is killed in a fresh lock // player can still change his mind, exit instance and reactivate old lock @@ -312,7 +318,12 @@ InstanceLock* InstanceLockMgr::UpdateInstanceLockForPlayer(CharacterDatabaseTran instanceLock = new InstanceLock(entries.MapDifficulty->MapID, Difficulty(entries.MapDifficulty->DifficultyID), GetNextResetTime(entries), updateEvent.InstanceId); - _instanceLocksByPlayer[playerGuid][entries.GetKey()].reset(instanceLock); + { + std::unique_lock<std::shared_mutex> guard(_locksMutex); + + _instanceLocksByPlayer[playerGuid][entries.GetKey()].reset(instanceLock); + } + TC_LOG_DEBUG("instance.locks", "[%u-%s | %u-%s] Created new instance lock for %s in instance %u", entries.Map->ID, entries.Map->MapName[sWorld->GetDefaultDbcLocale()], uint32(entries.MapDifficulty->DifficultyID), sDifficultyStore.AssertEntry(entries.MapDifficulty->DifficultyID)->Name[sWorld->GetDefaultDbcLocale()], diff --git a/src/server/game/Instances/InstanceLockMgr.h b/src/server/game/Instances/InstanceLockMgr.h index f905d7e6fe7..3f8aebf6d25 100644 --- a/src/server/game/Instances/InstanceLockMgr.h +++ b/src/server/game/Instances/InstanceLockMgr.h @@ -24,6 +24,7 @@ #include "Hash.h" #include "ObjectGuid.h" #include "Optional.h" +#include <shared_mutex> #include <unordered_map> /* @@ -192,7 +193,6 @@ struct InstanceLockUpdateEvent Optional<uint32> EntranceWorldSafeLocId; }; -// TOTALLY NOT THREADSAFE YET class TC_GAME_API InstanceLockMgr { public: @@ -283,6 +283,7 @@ private: static InstanceLock* FindInstanceLock(LockMap const& locks, ObjectGuid const& playerGuid, MapDb2Entries const& entries); InstanceLock* FindActiveInstanceLock(ObjectGuid const& playerGuid, MapDb2Entries const& entries, bool ignoreTemporary, bool ignoreExpired) const; + mutable std::shared_mutex _locksMutex; LockMap _temporaryInstanceLocksByPlayer; // locks stored here before any boss gets killed LockMap _instanceLocksByPlayer; std::unordered_map<uint32, std::weak_ptr<SharedInstanceLockData>> _instanceLockDataById; |