More robust checks on mutex acquire.

- When using ACE_xxx_Guard, the caller must ensure the internal lock is really acquired before entering the critical section
(see http://www.dre.vanderbilt.edu/Doxygen/6.0.1/html/libace-doc/a00186.html#_details - Warnings paragraph)
This commit is contained in:
H0zen 2016-03-04 14:30:48 +02:00
parent fc72b48f84
commit dbc21ed903
2 changed files with 75 additions and 57 deletions

View File

@ -93,12 +93,14 @@ Player* ObjectAccessor::FindPlayer(ObjectGuid guid, bool inWorld /*= true*/)
Player* ObjectAccessor::FindPlayerByName(const char* name) Player* ObjectAccessor::FindPlayerByName(const char* name)
{ {
HashMapHolder<Player>::ReadGuard g(HashMapHolder<Player>::GetLock()); HashMapHolder<Player>::ReadGuard g(HashMapHolder<Player>::GetLock(), true);
if (g.locked())
{
HashMapHolder<Player>::MapType& m = sObjectAccessor.GetPlayers(); HashMapHolder<Player>::MapType& m = sObjectAccessor.GetPlayers();
for (HashMapHolder<Player>::MapType::iterator iter = m.begin(); iter != m.end(); ++iter) for (HashMapHolder<Player>::MapType::iterator iter = m.begin(); iter != m.end(); ++iter)
if (iter->second->IsInWorld() && (::strcmp(name, iter->second->GetName()) == 0)) if (iter->second->IsInWorld() && (::strcmp(name, iter->second->GetName()) == 0))
{ return iter->second; } { return iter->second; }
}
return NULL; return NULL;
} }
@ -129,15 +131,16 @@ void ObjectAccessor::KickPlayer(ObjectGuid guid)
Corpse* Corpse*
ObjectAccessor::GetCorpseForPlayerGUID(ObjectGuid guid) ObjectAccessor::GetCorpseForPlayerGUID(ObjectGuid guid)
{ {
Guard guard(i_corpseGuard); ACE_Guard<LockType> guard(i_corpseGuard, true);
if (guard.locked())
{
Player2CorpsesMapType::iterator iter = i_player2corpse.find(guid); Player2CorpsesMapType::iterator iter = i_player2corpse.find(guid);
if (iter == i_player2corpse.end()) if (iter == i_player2corpse.end())
{ return NULL; } { return NULL; }
MANGOS_ASSERT(iter->second->GetType() != CORPSE_BONES); MANGOS_ASSERT(iter->second->GetType() != CORPSE_BONES);
return iter->second; return iter->second;
}
return NULL;
} }
void void
@ -145,7 +148,9 @@ ObjectAccessor::RemoveCorpse(Corpse* corpse)
{ {
MANGOS_ASSERT(corpse && corpse->GetType() != CORPSE_BONES); MANGOS_ASSERT(corpse && corpse->GetType() != CORPSE_BONES);
Guard guard(i_corpseGuard); ACE_Guard<LockType> guard(i_corpseGuard, true);
if (guard.locked())
{
Player2CorpsesMapType::iterator iter = i_player2corpse.find(corpse->GetOwnerGuid()); Player2CorpsesMapType::iterator iter = i_player2corpse.find(corpse->GetOwnerGuid());
if (iter == i_player2corpse.end()) if (iter == i_player2corpse.end())
{ return; } { return; }
@ -158,6 +163,7 @@ ObjectAccessor::RemoveCorpse(Corpse* corpse)
corpse->RemoveFromWorld(); corpse->RemoveFromWorld();
i_player2corpse.erase(iter); i_player2corpse.erase(iter);
}
} }
void void
@ -165,7 +171,9 @@ ObjectAccessor::AddCorpse(Corpse* corpse)
{ {
MANGOS_ASSERT(corpse && corpse->GetType() != CORPSE_BONES); MANGOS_ASSERT(corpse && corpse->GetType() != CORPSE_BONES);
Guard guard(i_corpseGuard); ACE_Guard<LockType> guard(i_corpseGuard, true);
if (guard.locked())
{
MANGOS_ASSERT(i_player2corpse.find(corpse->GetOwnerGuid()) == i_player2corpse.end()); MANGOS_ASSERT(i_player2corpse.find(corpse->GetOwnerGuid()) == i_player2corpse.end());
i_player2corpse[corpse->GetOwnerGuid()] = corpse; i_player2corpse[corpse->GetOwnerGuid()] = corpse;
@ -174,12 +182,15 @@ ObjectAccessor::AddCorpse(Corpse* corpse)
uint32 cell_id = (cell_pair.y_coord * TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord; uint32 cell_id = (cell_pair.y_coord * TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord;
sObjectMgr.AddCorpseCellData(corpse->GetMapId(), cell_id, corpse->GetOwnerGuid().GetCounter(), corpse->GetInstanceId()); sObjectMgr.AddCorpseCellData(corpse->GetMapId(), cell_id, corpse->GetOwnerGuid().GetCounter(), corpse->GetInstanceId());
}
} }
void void
ObjectAccessor::AddCorpsesToGrid(GridPair const& gridpair, GridType& grid, Map* map) ObjectAccessor::AddCorpsesToGrid(GridPair const& gridpair, GridType& grid, Map* map)
{ {
Guard guard(i_corpseGuard); ACE_Guard<LockType> guard(i_corpseGuard, true);
if (guard.locked())
{
for (Player2CorpsesMapType::iterator iter = i_player2corpse.begin(); iter != i_player2corpse.end(); ++iter) for (Player2CorpsesMapType::iterator iter = i_player2corpse.begin(); iter != i_player2corpse.end(); ++iter)
if (iter->second->GetGrid() == gridpair) if (iter->second->GetGrid() == gridpair)
{ {
@ -196,6 +207,7 @@ ObjectAccessor::AddCorpsesToGrid(GridPair const& gridpair, GridType& grid, Map*
grid.AddWorldObject(iter->second); grid.AddWorldObject(iter->second);
} }
} }
}
} }
Corpse* Corpse*

View File

@ -59,22 +59,29 @@ class HashMapHolder
static void Insert(T* o) static void Insert(T* o)
{ {
WriteGuard guard(i_lock); WriteGuard guard(i_lock, true);
if (guard.locked())
m_objectMap[o->GetObjectGuid()] = o; m_objectMap[o->GetObjectGuid()] = o;
} }
static void Remove(T* o) static void Remove(T* o)
{ {
WriteGuard guard(i_lock); WriteGuard guard(i_lock, true);
if (guard.locked())
m_objectMap.erase(o->GetObjectGuid()); m_objectMap.erase(o->GetObjectGuid());
} }
static T* Find(ObjectGuid guid) static T* Find(ObjectGuid guid)
{ {
ReadGuard guard(i_lock); ReadGuard guard(i_lock, true);
if (guard.locked())
{
typename MapType::iterator itr = m_objectMap.find(guid); typename MapType::iterator itr = m_objectMap.find(guid);
return (itr != m_objectMap.end()) ? itr->second : NULL; return (itr != m_objectMap.end()) ? itr->second : NULL;
} }
else
return NULL;
}
static MapType& GetContainer() { return m_objectMap; } static MapType& GetContainer() { return m_objectMap; }
@ -137,7 +144,6 @@ class ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor, MaNGOS::ClassLev
Player2CorpsesMapType i_player2corpse; Player2CorpsesMapType i_player2corpse;
typedef ACE_Thread_Mutex LockType; typedef ACE_Thread_Mutex LockType;
typedef MaNGOS::GeneralLock<LockType > Guard;
LockType i_playerGuard; LockType i_playerGuard;
LockType i_corpseGuard; LockType i_corpseGuard;