aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Instances/InstanceLockMgr.cpp13
-rw-r--r--src/server/game/Instances/InstanceLockMgr.h3
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;