Skip to content

Instantly share code, notes, and snippets.

@rsa
Created September 1, 2011 10:51
Show Gist options
  • Select an option

  • Save rsa/1185933 to your computer and use it in GitHub Desktop.

Select an option

Save rsa/1185933 to your computer and use it in GitHub Desktop.
Locking v3 part2 - second vesion
diff --git a/src/game/Object.h b/src/game/Object.h
index 7b06e3b..b9e7d64 100644
--- a/src/game/Object.h
+++ b/src/game/Object.h
@@ -651,4 +651,20 @@ class MANGOS_DLL_SPEC WorldObject : public Object
WorldUpdateCounter m_updateTracker;
};
+#ifndef MAPLOCK_READ(OBJ,TYPE)
+# define MAPLOCK_READ(OBJ,TYPE) Map::ReadGuard Guard((OBJ)->GetMap()->GetLock(TYPE));
+#endif
+
+#ifndef MAPLOCK_READ1(OBJ,TYPE)
+# define MAPLOCK_READ1(OBJ,TYPE) Map::ReadGuard Guard1((OBJ)->GetMap()->GetLock(TYPE));
+#endif
+
+#ifndef MAPLOCK_READ2(OBJ,TYPE)
+# define MAPLOCK_READ2(OBJ,TYPE) Map::ReadGuard Guard2((OBJ)->GetMap()->GetLock(TYPE));
+#endif
+
+#ifndef MAPLOCK_WRITE(OBJ,TYPE)
+# define MAPLOCK_WRITE(OBJ,TYPE) Map::WriteGuard Guard((OBJ)->GetMap()->GetLock(TYPE));
+#endif
+
#endif
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 272e832..45a1cee 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -5131,8 +5131,10 @@ SpellCastResult Spell::CheckCast(bool strict)
return m_caster->getClass() == CLASS_WARRIOR ? SPELL_FAILED_CASTER_AURASTATE : SPELL_FAILED_NO_COMBO_POINTS;
}
- if (Unit *target = m_targets.getUnitTarget())
+ Unit *target = m_targets.getUnitTarget();
+ if (target && target->IsInWorld() && target->GetMap())
{
+ MAPLOCK_READ(target,MAP_LOCK_TYPE_AURAS);
// target state requirements (not allowed state), apply to self also
// This check not need - checked in CheckTarget()
// if (m_spellInfo->TargetAuraStateNot && target->HasAuraState(AuraState(m_spellInfo->TargetAuraStateNot)))
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index ea37cbe..3981d79 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -340,7 +340,10 @@ void Unit::Update( uint32 update_diff, uint32 p_time )
m_Events.Update( update_diff );
_UpdateSpells( update_diff );
- CleanupDeletedAuras();
+ {
+ MAPLOCK_WRITE(this,MAP_LOCK_TYPE_AURAS);
+ CleanupDeletedAuras();
+ }
if (m_lastManaUseTimer)
{
@@ -3695,7 +3698,10 @@ void Unit::_UpdateSpells( uint32 time )
SpellAuraHolder* i_holder = m_spellAuraHoldersUpdateIterator->second;
++m_spellAuraHoldersUpdateIterator; // need shift to next for allow update if need into aura update
if (i_holder && !i_holder->IsDeleted() && !i_holder->IsEmptyHolder() && !i_holder->IsInUse())
+ {
+ MAPLOCK_READ(this,MAP_LOCK_TYPE_AURAS);
i_holder->UpdateHolder(time);
+ }
}
// remove expired auras
@@ -6776,13 +6782,18 @@ int32 Unit::SpellBonusWithCoeffs(SpellEntry const *spellProto, int32 total, int3
*/
uint32 Unit::SpellDamageBonusDone(Unit *pVictim, SpellEntry const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack)
{
- if(!spellProto || !pVictim || damagetype==DIRECT_DAMAGE || spellProto->AttributesEx6 & SPELL_ATTR_EX6_NO_DMG_MODS)
+ if(!spellProto || !pVictim || !pVictim->GetMap() || damagetype==DIRECT_DAMAGE || spellProto->AttributesEx6 & SPELL_ATTR_EX6_NO_DMG_MODS)
return pdamage;
// conflagrate gets damage mods from previously calculated immolate aura damage tick
if (spellProto->IsFitToFamily<SPELLFAMILY_WARLOCK, CF_WARLOCK_CONFLAGRATE>())
return pdamage;
+ if (!IsInWorld() || !GetMap())
+ return pdamage;
+
+ MAPLOCK_READ(this,MAP_LOCK_TYPE_AURAS);
+
// For totems get damage bonus from owner (statue isn't totem in fact)
if ( GetTypeId()==TYPEID_UNIT && ((Creature*)this)->IsTotem() && ((Totem*)this)->GetTotemType()!=TOTEM_STATUE)
{
@@ -6800,7 +6811,7 @@ uint32 Unit::SpellDamageBonusDone(Unit *pVictim, SpellEntry const *spellProto, u
float nonStackingPos = 0.0f;
float nonStackingNeg = 0.0f;
- AuraList const mModDamagePercentDone = GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
+ AuraList const& mModDamagePercentDone = GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
for(AuraList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i)
{
if (!*i)
@@ -6866,7 +6877,12 @@ uint32 Unit::SpellDamageBonusDone(Unit *pVictim, SpellEntry const *spellProto, u
// done scripted mod (take it from owner)
Unit *owner = GetOwner();
- if (!owner) owner = this;
+ if (!owner)
+ owner = this;
+
+ MAPLOCK_READ1(owner,MAP_LOCK_TYPE_AURAS);
+ MAPLOCK_READ2(pVictim,MAP_LOCK_TYPE_AURAS);
+
AuraList const& mOverrideClassScript= owner->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
for(AuraList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
{
@@ -7177,7 +7193,7 @@ uint32 Unit::SpellDamageBonusDone(Unit *pVictim, SpellEntry const *spellProto, u
*/
uint32 Unit::SpellDamageBonusTaken(Unit *pCaster, SpellEntry const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack)
{
- if(!spellProto || !pCaster || damagetype==DIRECT_DAMAGE )
+ if(!spellProto || !pCaster || !IsInWorld() || !GetMap() || damagetype==DIRECT_DAMAGE )
return pdamage;
uint32 schoolMask = spellProto->SchoolMask;
@@ -7186,6 +7202,8 @@ uint32 Unit::SpellDamageBonusTaken(Unit *pCaster, SpellEntry const *spellProto,
float TakenTotalMod = 1.0f;
int32 TakenTotal = 0;
+ MAPLOCK_READ(this,MAP_LOCK_TYPE_AURAS);
+
// ..taken
TakenTotalMod *= GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, schoolMask);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment