[9997] Some changes in HashMapHolder.

* Use ACE_RW_Thread_Mutex, since there's much more reading than writing.
* Use read lock in Find(), and write lock in Insert() and Remove().
* Correctly lock the hashmap on outside calls.
This commit is contained in:
XTZGZoReX 2010-05-28 15:30:23 +02:00
parent aa62225c68
commit a037a26fde
4 changed files with 36 additions and 27 deletions

View file

@ -153,21 +153,23 @@ bool ChatHandler::HandleGMListIngameCommand(const char* /*args*/)
{
bool first = true;
HashMapHolder<Player>::MapType &m = HashMapHolder<Player>::GetContainer();
HashMapHolder<Player>::MapType::const_iterator itr = m.begin();
for(; itr != m.end(); ++itr)
{
AccountTypes itr_sec = itr->second->GetSession()->GetSecurity();
if ((itr->second->isGameMaster() || (itr_sec > SEC_PLAYER && itr_sec <= (AccountTypes)sWorld.getConfig(CONFIG_UINT32_GM_LEVEL_IN_GM_LIST))) &&
(!m_session || itr->second->IsVisibleGloballyFor(m_session->GetPlayer())))
HashMapHolder<Player>::ReadGuard g(HashMapHolder<Player>::GetLock());
HashMapHolder<Player>::MapType &m = sObjectAccessor.GetPlayers();
for(HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr)
{
if(first)
AccountTypes itr_sec = itr->second->GetSession()->GetSecurity();
if ((itr->second->isGameMaster() || (itr_sec > SEC_PLAYER && itr_sec <= (AccountTypes)sWorld.getConfig(CONFIG_UINT32_GM_LEVEL_IN_GM_LIST))) &&
(!m_session || itr->second->IsVisibleGloballyFor(m_session->GetPlayer())))
{
SendSysMessage(LANG_GMS_ON_SRV);
first = false;
}
if(first)
{
SendSysMessage(LANG_GMS_ON_SRV);
first = false;
}
SendSysMessage(GetNameLink(itr->second).c_str());
SendSysMessage(GetNameLink(itr->second).c_str());
}
}
}

View file

@ -92,22 +92,21 @@ ObjectAccessor::FindPlayer(ObjectGuid guid)
Player*
ObjectAccessor::FindPlayerByName(const char *name)
{
//TODO: Player Guard
HashMapHolder<Player>::MapType& m = HashMapHolder<Player>::GetContainer();
HashMapHolder<Player>::MapType::iterator iter = m.begin();
for(; iter != m.end(); ++iter)
HashMapHolder<Player>::ReadGuard g(HashMapHolder<Player>::GetLock());
HashMapHolder<Player>::MapType& m = sObjectAccessor.GetPlayers();
for(HashMapHolder<Player>::MapType::iterator iter = m.begin(); iter != m.end(); ++iter)
if(iter->second->IsInWorld() && ( ::strcmp(name, iter->second->GetName()) == 0 ))
return iter->second;
return NULL;
}
void
ObjectAccessor::SaveAllPlayers()
{
Guard guard(*HashMapHolder<Player>::GetLock());
HashMapHolder<Player>::MapType& m = HashMapHolder<Player>::GetContainer();
HashMapHolder<Player>::MapType::iterator itr = m.begin();
for(; itr != m.end(); ++itr)
HashMapHolder<Player>::ReadGuard g(HashMapHolder<Player>::GetLock());
HashMapHolder<Player>::MapType& m = sObjectAccessor.GetPlayers();
for(HashMapHolder<Player>::MapType::iterator itr = m.begin(); itr != m.end(); ++itr)
itr->second->SaveToDB();
}
@ -277,7 +276,7 @@ void ObjectAccessor::RemoveOldCorpses()
/// Define the static member of HashMapHolder
template <class T> UNORDERED_MAP< uint64, T* > HashMapHolder<T>::m_objectMap;
template <class T> ACE_Thread_Mutex HashMapHolder<T>::i_lock;
template <class T> ACE_RW_Thread_Mutex HashMapHolder<T>::i_lock;
/// Global definitions for the hashmap storage

View file

@ -22,6 +22,7 @@
#include "Platform/Define.h"
#include "Policies/Singleton.h"
#include <ace/Thread_Mutex.h>
#include <ace/RW_Thread_Mutex.h>
#include "Utilities/UnorderedMap.h"
#include "Policies/ThreadingModel.h"
@ -47,26 +48,33 @@ class HashMapHolder
public:
typedef UNORDERED_MAP< uint64, T* > MapType;
typedef ACE_Thread_Mutex LockType;
typedef MaNGOS::GeneralLock<LockType > Guard;
typedef ACE_RW_Thread_Mutex LockType;
typedef ACE_Read_Guard<LockType> ReadGuard;
typedef ACE_Write_Guard<LockType> WriteGuard;
static void Insert(T* o) { m_objectMap[o->GetGUID()] = o; }
static void Insert(T* o)
{
WriteGuard guard(i_lock);
m_objectMap[o->GetGUID()] = o;
}
static void Remove(T* o)
{
Guard guard(i_lock);
WriteGuard guard(i_lock);
m_objectMap.erase(o->GetGUID());
}
static T* Find(ObjectGuid guid)
{
ReadGuard guard(i_lock);
typename MapType::iterator itr = m_objectMap.find(guid.GetRawValue());
return (itr != m_objectMap.end()) ? itr->second : NULL;
}
static MapType& GetContainer() { return m_objectMap; }
static LockType* GetLock() { return &i_lock; }
static LockType& GetLock() { return i_lock; }
private:
//Non instanceable only static
@ -78,8 +86,8 @@ class HashMapHolder
class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor, MaNGOS::ClassLevelLockable<ObjectAccessor, ACE_Thread_Mutex> >
{
friend class MaNGOS::OperatorNew<ObjectAccessor>;
ObjectAccessor();
~ObjectAccessor();
ObjectAccessor(const ObjectAccessor &);

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "9996"
#define REVISION_NR "9997"
#endif // __REVISION_NR_H__