From 8be06161283af3992271de1868881ab4079a2ca8 Mon Sep 17 00:00:00 2001 From: MobiusDev <8391001+MobiusDevelopment@users.noreply.github.com> Date: Mon, 5 Jun 2017 11:29:24 +0000 Subject: [PATCH] Fixed recalculateStats deadlock. --- .../gameserver/model/actor/stat/CharStat.java | 52 +++++++++---------- .../gameserver/model/actor/stat/CharStat.java | 52 +++++++++---------- .../gameserver/model/actor/stat/CharStat.java | 52 +++++++++---------- 3 files changed, 78 insertions(+), 78 deletions(-) diff --git a/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/model/actor/stat/CharStat.java b/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/model/actor/stat/CharStat.java index 61a92bf527..4b0d66b208 100644 --- a/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/model/actor/stat/CharStat.java +++ b/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/model/actor/stat/CharStat.java @@ -733,13 +733,13 @@ public class CharStat */ public final void recalculateStats(boolean broadcast) { + // Copy old data before wiping it out + final Map adds = !broadcast ? Collections.emptyMap() : new HashMap<>(_statsAdd); + final Map muls = !broadcast ? Collections.emptyMap() : new HashMap<>(_statsMul); + _lock.writeLock().lock(); try { - // Copy old data before wiping it out - final Map adds = !broadcast ? Collections.emptyMap() : new HashMap<>(_statsAdd); - final Map muls = !broadcast ? Collections.emptyMap() : new HashMap<>(_statsMul); - // Wipe all the data resetStats(); @@ -760,33 +760,33 @@ public class CharStat // Merge with additional stats _additionalAdd.stream().filter(holder -> holder.verifyCondition(_activeChar)).forEach(holder -> mergeAdd(holder.getStat(), holder.getValue())); _additionalMul.stream().filter(holder -> holder.verifyCondition(_activeChar)).forEach(holder -> mergeMul(holder.getStat(), holder.getValue())); - - // Notify recalculation to child classes - onRecalculateStats(broadcast); - - if (broadcast) - { - // Calculate the difference between old and new stats - final Set changed = new HashSet<>(); - for (Stats stat : Stats.values()) - { - if (_statsAdd.getOrDefault(stat, stat.getResetAddValue()) != adds.getOrDefault(stat, stat.getResetAddValue())) - { - changed.add(stat); - } - else if (_statsMul.getOrDefault(stat, stat.getResetMulValue()) != muls.getOrDefault(stat, stat.getResetMulValue())) - { - changed.add(stat); - } - } - - _activeChar.broadcastModifiedStats(changed); - } } finally { _lock.writeLock().unlock(); } + + // Notify recalculation to child classes + onRecalculateStats(broadcast); + + if (broadcast) + { + // Calculate the difference between old and new stats + final Set changed = new HashSet<>(); + for (Stats stat : Stats.values()) + { + if (_statsAdd.getOrDefault(stat, stat.getResetAddValue()) != adds.getOrDefault(stat, stat.getResetAddValue())) + { + changed.add(stat); + } + else if (_statsMul.getOrDefault(stat, stat.getResetMulValue()) != muls.getOrDefault(stat, stat.getResetMulValue())) + { + changed.add(stat); + } + } + + _activeChar.broadcastModifiedStats(changed); + } } protected void onRecalculateStats(boolean broadcast) diff --git a/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/model/actor/stat/CharStat.java b/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/model/actor/stat/CharStat.java index 61a92bf527..4b0d66b208 100644 --- a/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/model/actor/stat/CharStat.java +++ b/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/model/actor/stat/CharStat.java @@ -733,13 +733,13 @@ public class CharStat */ public final void recalculateStats(boolean broadcast) { + // Copy old data before wiping it out + final Map adds = !broadcast ? Collections.emptyMap() : new HashMap<>(_statsAdd); + final Map muls = !broadcast ? Collections.emptyMap() : new HashMap<>(_statsMul); + _lock.writeLock().lock(); try { - // Copy old data before wiping it out - final Map adds = !broadcast ? Collections.emptyMap() : new HashMap<>(_statsAdd); - final Map muls = !broadcast ? Collections.emptyMap() : new HashMap<>(_statsMul); - // Wipe all the data resetStats(); @@ -760,33 +760,33 @@ public class CharStat // Merge with additional stats _additionalAdd.stream().filter(holder -> holder.verifyCondition(_activeChar)).forEach(holder -> mergeAdd(holder.getStat(), holder.getValue())); _additionalMul.stream().filter(holder -> holder.verifyCondition(_activeChar)).forEach(holder -> mergeMul(holder.getStat(), holder.getValue())); - - // Notify recalculation to child classes - onRecalculateStats(broadcast); - - if (broadcast) - { - // Calculate the difference between old and new stats - final Set changed = new HashSet<>(); - for (Stats stat : Stats.values()) - { - if (_statsAdd.getOrDefault(stat, stat.getResetAddValue()) != adds.getOrDefault(stat, stat.getResetAddValue())) - { - changed.add(stat); - } - else if (_statsMul.getOrDefault(stat, stat.getResetMulValue()) != muls.getOrDefault(stat, stat.getResetMulValue())) - { - changed.add(stat); - } - } - - _activeChar.broadcastModifiedStats(changed); - } } finally { _lock.writeLock().unlock(); } + + // Notify recalculation to child classes + onRecalculateStats(broadcast); + + if (broadcast) + { + // Calculate the difference between old and new stats + final Set changed = new HashSet<>(); + for (Stats stat : Stats.values()) + { + if (_statsAdd.getOrDefault(stat, stat.getResetAddValue()) != adds.getOrDefault(stat, stat.getResetAddValue())) + { + changed.add(stat); + } + else if (_statsMul.getOrDefault(stat, stat.getResetMulValue()) != muls.getOrDefault(stat, stat.getResetMulValue())) + { + changed.add(stat); + } + } + + _activeChar.broadcastModifiedStats(changed); + } } protected void onRecalculateStats(boolean broadcast) diff --git a/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/model/actor/stat/CharStat.java b/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/model/actor/stat/CharStat.java index 61a92bf527..4b0d66b208 100644 --- a/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/model/actor/stat/CharStat.java +++ b/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/model/actor/stat/CharStat.java @@ -733,13 +733,13 @@ public class CharStat */ public final void recalculateStats(boolean broadcast) { + // Copy old data before wiping it out + final Map adds = !broadcast ? Collections.emptyMap() : new HashMap<>(_statsAdd); + final Map muls = !broadcast ? Collections.emptyMap() : new HashMap<>(_statsMul); + _lock.writeLock().lock(); try { - // Copy old data before wiping it out - final Map adds = !broadcast ? Collections.emptyMap() : new HashMap<>(_statsAdd); - final Map muls = !broadcast ? Collections.emptyMap() : new HashMap<>(_statsMul); - // Wipe all the data resetStats(); @@ -760,33 +760,33 @@ public class CharStat // Merge with additional stats _additionalAdd.stream().filter(holder -> holder.verifyCondition(_activeChar)).forEach(holder -> mergeAdd(holder.getStat(), holder.getValue())); _additionalMul.stream().filter(holder -> holder.verifyCondition(_activeChar)).forEach(holder -> mergeMul(holder.getStat(), holder.getValue())); - - // Notify recalculation to child classes - onRecalculateStats(broadcast); - - if (broadcast) - { - // Calculate the difference between old and new stats - final Set changed = new HashSet<>(); - for (Stats stat : Stats.values()) - { - if (_statsAdd.getOrDefault(stat, stat.getResetAddValue()) != adds.getOrDefault(stat, stat.getResetAddValue())) - { - changed.add(stat); - } - else if (_statsMul.getOrDefault(stat, stat.getResetMulValue()) != muls.getOrDefault(stat, stat.getResetMulValue())) - { - changed.add(stat); - } - } - - _activeChar.broadcastModifiedStats(changed); - } } finally { _lock.writeLock().unlock(); } + + // Notify recalculation to child classes + onRecalculateStats(broadcast); + + if (broadcast) + { + // Calculate the difference between old and new stats + final Set changed = new HashSet<>(); + for (Stats stat : Stats.values()) + { + if (_statsAdd.getOrDefault(stat, stat.getResetAddValue()) != adds.getOrDefault(stat, stat.getResetAddValue())) + { + changed.add(stat); + } + else if (_statsMul.getOrDefault(stat, stat.getResetMulValue()) != muls.getOrDefault(stat, stat.getResetMulValue())) + { + changed.add(stat); + } + } + + _activeChar.broadcastModifiedStats(changed); + } } protected void onRecalculateStats(boolean broadcast)