mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 22:37:03 +00:00
[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:
parent
aa62225c68
commit
a037a26fde
4 changed files with 36 additions and 27 deletions
|
|
@ -153,21 +153,23 @@ bool ChatHandler::HandleGMListIngameCommand(const char* /*args*/)
|
||||||
{
|
{
|
||||||
bool first = true;
|
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();
|
HashMapHolder<Player>::ReadGuard g(HashMapHolder<Player>::GetLock());
|
||||||
if ((itr->second->isGameMaster() || (itr_sec > SEC_PLAYER && itr_sec <= (AccountTypes)sWorld.getConfig(CONFIG_UINT32_GM_LEVEL_IN_GM_LIST))) &&
|
HashMapHolder<Player>::MapType &m = sObjectAccessor.GetPlayers();
|
||||||
(!m_session || itr->second->IsVisibleGloballyFor(m_session->GetPlayer())))
|
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);
|
if(first)
|
||||||
first = false;
|
{
|
||||||
}
|
SendSysMessage(LANG_GMS_ON_SRV);
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
SendSysMessage(GetNameLink(itr->second).c_str());
|
SendSysMessage(GetNameLink(itr->second).c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -92,22 +92,21 @@ ObjectAccessor::FindPlayer(ObjectGuid guid)
|
||||||
Player*
|
Player*
|
||||||
ObjectAccessor::FindPlayerByName(const char *name)
|
ObjectAccessor::FindPlayerByName(const char *name)
|
||||||
{
|
{
|
||||||
//TODO: Player Guard
|
HashMapHolder<Player>::ReadGuard g(HashMapHolder<Player>::GetLock());
|
||||||
HashMapHolder<Player>::MapType& m = HashMapHolder<Player>::GetContainer();
|
HashMapHolder<Player>::MapType& m = sObjectAccessor.GetPlayers();
|
||||||
HashMapHolder<Player>::MapType::iterator iter = m.begin();
|
for(HashMapHolder<Player>::MapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||||
for(; 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ObjectAccessor::SaveAllPlayers()
|
ObjectAccessor::SaveAllPlayers()
|
||||||
{
|
{
|
||||||
Guard guard(*HashMapHolder<Player>::GetLock());
|
HashMapHolder<Player>::ReadGuard g(HashMapHolder<Player>::GetLock());
|
||||||
HashMapHolder<Player>::MapType& m = HashMapHolder<Player>::GetContainer();
|
HashMapHolder<Player>::MapType& m = sObjectAccessor.GetPlayers();
|
||||||
HashMapHolder<Player>::MapType::iterator itr = m.begin();
|
for(HashMapHolder<Player>::MapType::iterator itr = m.begin(); itr != m.end(); ++itr)
|
||||||
for(; itr != m.end(); ++itr)
|
|
||||||
itr->second->SaveToDB();
|
itr->second->SaveToDB();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -277,7 +276,7 @@ void ObjectAccessor::RemoveOldCorpses()
|
||||||
/// Define the static member of HashMapHolder
|
/// Define the static member of HashMapHolder
|
||||||
|
|
||||||
template <class T> UNORDERED_MAP< uint64, T* > HashMapHolder<T>::m_objectMap;
|
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
|
/// Global definitions for the hashmap storage
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
#include "Platform/Define.h"
|
#include "Platform/Define.h"
|
||||||
#include "Policies/Singleton.h"
|
#include "Policies/Singleton.h"
|
||||||
#include <ace/Thread_Mutex.h>
|
#include <ace/Thread_Mutex.h>
|
||||||
|
#include <ace/RW_Thread_Mutex.h>
|
||||||
#include "Utilities/UnorderedMap.h"
|
#include "Utilities/UnorderedMap.h"
|
||||||
#include "Policies/ThreadingModel.h"
|
#include "Policies/ThreadingModel.h"
|
||||||
|
|
||||||
|
|
@ -47,26 +48,33 @@ class HashMapHolder
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef UNORDERED_MAP< uint64, T* > MapType;
|
typedef UNORDERED_MAP< uint64, T* > MapType;
|
||||||
typedef ACE_Thread_Mutex LockType;
|
typedef ACE_RW_Thread_Mutex LockType;
|
||||||
typedef MaNGOS::GeneralLock<LockType > Guard;
|
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)
|
static void Remove(T* o)
|
||||||
{
|
{
|
||||||
Guard guard(i_lock);
|
WriteGuard guard(i_lock);
|
||||||
m_objectMap.erase(o->GetGUID());
|
m_objectMap.erase(o->GetGUID());
|
||||||
}
|
}
|
||||||
|
|
||||||
static T* Find(ObjectGuid guid)
|
static T* Find(ObjectGuid guid)
|
||||||
{
|
{
|
||||||
|
ReadGuard guard(i_lock);
|
||||||
typename MapType::iterator itr = m_objectMap.find(guid.GetRawValue());
|
typename MapType::iterator itr = m_objectMap.find(guid.GetRawValue());
|
||||||
return (itr != m_objectMap.end()) ? itr->second : NULL;
|
return (itr != m_objectMap.end()) ? itr->second : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MapType& GetContainer() { return m_objectMap; }
|
static MapType& GetContainer() { return m_objectMap; }
|
||||||
|
|
||||||
static LockType* GetLock() { return &i_lock; }
|
static LockType& GetLock() { return i_lock; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
//Non instanceable only static
|
//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> >
|
class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor, MaNGOS::ClassLevelLockable<ObjectAccessor, ACE_Thread_Mutex> >
|
||||||
{
|
{
|
||||||
|
|
||||||
friend class MaNGOS::OperatorNew<ObjectAccessor>;
|
friend class MaNGOS::OperatorNew<ObjectAccessor>;
|
||||||
|
|
||||||
ObjectAccessor();
|
ObjectAccessor();
|
||||||
~ObjectAccessor();
|
~ObjectAccessor();
|
||||||
ObjectAccessor(const ObjectAccessor &);
|
ObjectAccessor(const ObjectAccessor &);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "9996"
|
#define REVISION_NR "9997"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue