Stop using monitored locks in EventInstanceManager

This commit is contained in:
P0nk
2022-08-11 13:56:12 +02:00
parent 42043c3d6c
commit 8ab2058ecc

View File

@@ -26,11 +26,6 @@ import client.Skill;
import client.SkillFactory; import client.SkillFactory;
import config.YamlConfig; import config.YamlConfig;
import constants.inventory.ItemConstants; import constants.inventory.ItemConstants;
import net.server.audit.LockCollector;
import net.server.audit.locks.*;
import net.server.audit.locks.factory.MonitoredReadLockFactory;
import net.server.audit.locks.factory.MonitoredReentrantLockFactory;
import net.server.audit.locks.factory.MonitoredWriteLockFactory;
import net.server.coordinator.world.EventRecallCoordinator; import net.server.coordinator.world.EventRecallCoordinator;
import net.server.world.Party; import net.server.world.Party;
import net.server.world.PartyCharacter; import net.server.world.PartyCharacter;
@@ -58,6 +53,10 @@ import java.awt.*;
import java.util.List; import java.util.List;
import java.util.*; import java.util.*;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import static java.util.concurrent.TimeUnit.MINUTES; import static java.util.concurrent.TimeUnit.MINUTES;
@@ -82,12 +81,11 @@ public class EventInstanceManager {
private Expedition expedition = null; private Expedition expedition = null;
private final List<Integer> mapIds = new LinkedList<>(); private final List<Integer> mapIds = new LinkedList<>();
private final MonitoredReentrantReadWriteLock lock = new MonitoredReentrantReadWriteLock(MonitoredLockType.EIM, true); private final Lock readLock;
private final MonitoredReadLock rL = MonitoredReadLockFactory.createLock(lock); private final Lock writeLock;
private final MonitoredWriteLock wL = MonitoredWriteLockFactory.createLock(lock);
private MonitoredReentrantLock pL = MonitoredReentrantLockFactory.createLock(MonitoredLockType.EIM_PARTY, true); private final Lock propertyLock = new ReentrantLock(true);
private MonitoredReentrantLock sL = MonitoredReentrantLockFactory.createLock(MonitoredLockType.EIM_SCRIPT, true); private final Lock scriptLock = new ReentrantLock(true);
private ScheduledFuture<?> event_schedule = null; private ScheduledFuture<?> event_schedule = null;
private boolean disposed = false; private boolean disposed = false;
@@ -117,6 +115,10 @@ public class EventInstanceManager {
this.name = name; this.name = name;
this.ess = new EventScriptScheduler(); this.ess = new EventScriptScheduler();
this.mapManager = new MapManager(this, em.getWorldServer().getId(), em.getChannelServer().getId()); this.mapManager = new MapManager(this, em.getWorldServer().getId(), em.getChannelServer().getId());
ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);
this.readLock = readWriteLock.readLock();
this.writeLock = readWriteLock.writeLock();
} }
public void setName(String name) { public void setName(String name) {
@@ -124,11 +126,11 @@ public class EventInstanceManager {
} }
public EventManager getEm() { public EventManager getEm() {
sL.lock(); scriptLock.lock();
try { try {
return em; return em;
} finally { } finally {
sL.unlock(); scriptLock.unlock();
} }
} }
@@ -239,7 +241,7 @@ public class EventInstanceManager {
return; return;
} }
wL.lock(); writeLock.lock();
try { try {
if (chars.containsKey(chr.getId())) { if (chars.containsKey(chr.getId())) {
return; return;
@@ -248,7 +250,7 @@ public class EventInstanceManager {
chars.put(chr.getId(), chr); chars.put(chr.getId(), chr);
chr.setEventInstance(this); chr.setEventInstance(this);
} finally { } finally {
wL.unlock(); writeLock.unlock();
} }
if (runEntryScript) { if (runEntryScript) {
@@ -391,12 +393,12 @@ public class EventInstanceManager {
log.error("Event script {} does not implement the playerUnregistered function", em.getName(), ex); log.error("Event script {} does not implement the playerUnregistered function", em.getName(), ex);
} }
wL.lock(); writeLock.lock();
try { try {
chars.remove(chr.getId()); chars.remove(chr.getId());
chr.setEventInstance(null); chr.setEventInstance(null);
} finally { } finally {
wL.unlock(); writeLock.unlock();
} }
gridRemove(chr); gridRemove(chr);
@@ -404,38 +406,38 @@ public class EventInstanceManager {
} }
public int getPlayerCount() { public int getPlayerCount() {
rL.lock(); readLock.lock();
try { try {
return chars.size(); return chars.size();
} finally { } finally {
rL.unlock(); readLock.unlock();
} }
} }
public Character getPlayerById(int id) { public Character getPlayerById(int id) {
rL.lock(); readLock.lock();
try { try {
return chars.get(id); return chars.get(id);
} finally { } finally {
rL.unlock(); readLock.unlock();
} }
} }
public List<Character> getPlayers() { public List<Character> getPlayers() {
rL.lock(); readLock.lock();
try { try {
return new ArrayList<>(chars.values()); return new ArrayList<>(chars.values());
} finally { } finally {
rL.unlock(); readLock.unlock();
} }
} }
private List<Character> getPlayerList() { private List<Character> getPlayerList() {
rL.lock(); readLock.lock();
try { try {
return new LinkedList<>(chars.values()); return new LinkedList<>(chars.values());
} finally { } finally {
rL.unlock(); readLock.unlock();
} }
} }
@@ -480,7 +482,7 @@ public class EventInstanceManager {
public void monsterKilled(final Monster mob, final boolean hasKiller) { public void monsterKilled(final Monster mob, final boolean hasKiller) {
int scriptResult = 0; int scriptResult = 0;
sL.lock(); scriptLock.lock();
try { try {
mobs.remove(mob); mobs.remove(mob);
@@ -492,7 +494,7 @@ public class EventInstanceManager {
} }
} }
} finally { } finally {
sL.unlock(); scriptLock.unlock();
} }
if (scriptResult > 0) { if (scriptResult > 0) {
@@ -598,13 +600,13 @@ public class EventInstanceManager {
} }
public void dispose() { public void dispose() {
rL.lock(); readLock.lock();
try { try {
for (Character chr : chars.values()) { for (Character chr : chars.values()) {
chr.setEventInstance(null); chr.setEventInstance(null);
} }
} finally { } finally {
rL.unlock(); readLock.unlock();
} }
dispose(false); dispose(false);
@@ -624,7 +626,7 @@ public class EventInstanceManager {
ess.dispose(); ess.dispose();
wL.lock(); writeLock.lock();
try { try {
for (Character chr : chars.values()) { for (Character chr : chars.values()) {
chr.setEventInstance(null); chr.setEventInstance(null);
@@ -633,7 +635,7 @@ public class EventInstanceManager {
mobs.clear(); mobs.clear();
ess = null; ess = null;
} finally { } finally {
wL.unlock(); writeLock.unlock();
} }
if (event_schedule != null) { if (event_schedule != null) {
@@ -648,44 +650,33 @@ public class EventInstanceManager {
disposeExpedition(); disposeExpedition();
sL.lock(); scriptLock.lock();
try { try {
if (!eventCleared) { if (!eventCleared) {
em.disposeInstance(name); em.disposeInstance(name);
} }
} finally { } finally {
sL.unlock(); scriptLock.unlock();
} }
TimerManager.getInstance().schedule(() -> { TimerManager.getInstance().schedule(() -> {
mapManager.dispose(); // issues from instantly disposing some event objects found thanks to MedicOP mapManager.dispose(); // issues from instantly disposing some event objects found thanks to MedicOP
wL.lock(); writeLock.lock();
try { try {
mapManager = null; mapManager = null;
em = null; em = null;
} finally { } finally {
wL.unlock(); writeLock.unlock();
} }
disposeLocks();
}, MINUTES.toMillis(1)); }, MINUTES.toMillis(1));
} }
private void disposeLocks() {
LockCollector.getInstance().registerDisposeAction(() -> emptyLocks());
}
private void emptyLocks() {
pL = pL.dispose();
sL = sL.dispose();
}
public MapManager getMapFactory() { public MapManager getMapFactory() {
return mapManager; return mapManager;
} }
public void schedule(final String methodName, long delay) { public void schedule(final String methodName, long delay) {
rL.lock(); readLock.lock();
try { try {
if (ess != null) { if (ess != null) {
Runnable r = () -> { Runnable r = () -> {
@@ -699,7 +690,7 @@ public class EventInstanceManager {
ess.registerEntry(r, delay); ess.registerEntry(r, delay);
} }
} finally { } finally {
rL.unlock(); readLock.unlock();
} }
} }
@@ -712,13 +703,13 @@ public class EventInstanceManager {
map.setEventInstance(this); map.setEventInstance(this);
if (!mapManager.isMapLoaded(mapId)) { if (!mapManager.isMapLoaded(mapId)) {
sL.lock(); scriptLock.lock();
try { try {
if (em.getProperty("shuffleReactors") != null && em.getProperty("shuffleReactors").equals("true")) { if (em.getProperty("shuffleReactors") != null && em.getProperty("shuffleReactors").equals("true")) {
map.shuffleReactors(); map.shuffleReactors();
} }
} finally { } finally {
sL.unlock(); scriptLock.unlock();
} }
} }
return map; return map;
@@ -733,56 +724,56 @@ public class EventInstanceManager {
} }
public void setProperty(String key, String value) { public void setProperty(String key, String value) {
pL.lock(); propertyLock.lock();
try { try {
props.setProperty(key, value); props.setProperty(key, value);
} finally { } finally {
pL.unlock(); propertyLock.unlock();
} }
} }
public Object setProperty(String key, String value, boolean prev) { public Object setProperty(String key, String value, boolean prev) {
pL.lock(); propertyLock.lock();
try { try {
return props.setProperty(key, value); return props.setProperty(key, value);
} finally { } finally {
pL.unlock(); propertyLock.unlock();
} }
} }
public void setObjectProperty(String key, Object obj) { public void setObjectProperty(String key, Object obj) {
pL.lock(); propertyLock.lock();
try { try {
objectProps.put(key, obj); objectProps.put(key, obj);
} finally { } finally {
pL.unlock(); propertyLock.unlock();
} }
} }
public String getProperty(String key) { public String getProperty(String key) {
pL.lock(); propertyLock.lock();
try { try {
return props.getProperty(key); return props.getProperty(key);
} finally { } finally {
pL.unlock(); propertyLock.unlock();
} }
} }
public int getIntProperty(String key) { public int getIntProperty(String key) {
pL.lock(); propertyLock.lock();
try { try {
return Integer.parseInt(props.getProperty(key)); return Integer.parseInt(props.getProperty(key));
} finally { } finally {
pL.unlock(); propertyLock.unlock();
} }
} }
public Object getObjectProperty(String key) { public Object getObjectProperty(String key) {
pL.lock(); propertyLock.lock();
try { try {
return objectProps.get(key); return objectProps.get(key);
} finally { } finally {
pL.unlock(); propertyLock.unlock();
} }
} }
@@ -957,11 +948,11 @@ public class EventInstanceManager {
public final void setExclusiveItems(List<Object> items) { public final void setExclusiveItems(List<Object> items) {
List<Integer> exclusive = convertToIntegerList(items); List<Integer> exclusive = convertToIntegerList(items);
wL.lock(); writeLock.lock();
try { try {
exclusiveItems.addAll(exclusive); exclusiveItems.addAll(exclusive);
} finally { } finally {
wL.unlock(); writeLock.unlock();
} }
} }
@@ -989,13 +980,13 @@ public class EventInstanceManager {
List<Integer> rewardQtys = convertToIntegerList(qtys); List<Integer> rewardQtys = convertToIntegerList(qtys);
//rewardsSet and rewardsQty hold temporary values //rewardsSet and rewardsQty hold temporary values
wL.lock(); writeLock.lock();
try { try {
collectionSet.put(eventLevel, rewardIds); collectionSet.put(eventLevel, rewardIds);
collectionQty.put(eventLevel, rewardQtys); collectionQty.put(eventLevel, rewardQtys);
collectionExp.put(eventLevel, expGiven); collectionExp.put(eventLevel, expGiven);
} finally { } finally {
wL.unlock(); writeLock.unlock();
} }
} }
@@ -1036,7 +1027,7 @@ public class EventInstanceManager {
List<Integer> rewardsSet, rewardsQty; List<Integer> rewardsSet, rewardsQty;
Integer rewardExp; Integer rewardExp;
rL.lock(); readLock.lock();
try { try {
eventLevel--; //event level starts counting from 1 eventLevel--; //event level starts counting from 1
if (eventLevel >= collectionSet.size()) { if (eventLevel >= collectionSet.size()) {
@@ -1048,7 +1039,7 @@ public class EventInstanceManager {
rewardExp = collectionExp.get(eventLevel); rewardExp = collectionExp.get(eventLevel);
} finally { } finally {
rL.unlock(); readLock.unlock();
} }
if (rewardExp == null) { if (rewardExp == null) {
@@ -1080,11 +1071,11 @@ public class EventInstanceManager {
if (expedition != null) { if (expedition != null) {
expedition.dispose(eventCleared); expedition.dispose(eventCleared);
sL.lock(); scriptLock.lock();
try { try {
expedition.removeChannelExpedition(em.getChannelServer()); expedition.removeChannelExpedition(em.getChannelServer());
} finally { } finally {
sL.unlock(); scriptLock.unlock();
} }
expedition = null; expedition = null;
@@ -1108,11 +1099,11 @@ public class EventInstanceManager {
chr.awardQuestPoint(YamlConfig.config.server.QUEST_POINT_PER_EVENT_CLEAR); chr.awardQuestPoint(YamlConfig.config.server.QUEST_POINT_PER_EVENT_CLEAR);
} }
sL.lock(); scriptLock.lock();
try { try {
em.disposeInstance(name); em.disposeInstance(name);
} finally { } finally {
sL.unlock(); scriptLock.unlock();
} }
disposeExpedition(); disposeExpedition();
@@ -1168,7 +1159,7 @@ public class EventInstanceManager {
} }
public final boolean isEventTeamTogether() { public final boolean isEventTeamTogether() {
rL.lock(); readLock.lock();
try { try {
if (chars.size() <= 1) { if (chars.size() <= 1) {
return true; return true;
@@ -1187,7 +1178,7 @@ public class EventInstanceManager {
return true; return true;
} finally { } finally {
rL.unlock(); readLock.unlock();
} }
} }
@@ -1228,29 +1219,29 @@ public class EventInstanceManager {
} }
public final int getLeaderId() { public final int getLeaderId() {
rL.lock(); readLock.lock();
try { try {
return leaderId; return leaderId;
} finally { } finally {
rL.unlock(); readLock.unlock();
} }
} }
public Character getLeader() { public Character getLeader() {
rL.lock(); readLock.lock();
try { try {
return chars.get(leaderId); return chars.get(leaderId);
} finally { } finally {
rL.unlock(); readLock.unlock();
} }
} }
public final void setLeader(Character chr) { public final void setLeader(Character chr) {
wL.lock(); writeLock.lock();
try { try {
leaderId = chr.getId(); leaderId = chr.getId();
} finally { } finally {
wL.unlock(); writeLock.unlock();
} }
} }
@@ -1293,11 +1284,11 @@ public class EventInstanceManager {
map.broadcastMessage(PacketCreator.playSound("Party1/Clear")); map.broadcastMessage(PacketCreator.playSound("Party1/Clear"));
if (hasGate) { if (hasGate) {
map.broadcastMessage(PacketCreator.environmentChange(mapObj, newState)); map.broadcastMessage(PacketCreator.environmentChange(mapObj, newState));
wL.lock(); writeLock.lock();
try { try {
openedGates.put(map.getId(), new Pair<>(mapObj, newState)); openedGates.put(map.getId(), new Pair<>(mapObj, newState));
} finally { } finally {
wL.unlock(); writeLock.unlock();
} }
} }
} }
@@ -1305,13 +1296,13 @@ public class EventInstanceManager {
public final void recoverOpenedGate(Character chr, int thisMapId) { public final void recoverOpenedGate(Character chr, int thisMapId) {
Pair<String, Integer> gateData = null; Pair<String, Integer> gateData = null;
rL.lock(); readLock.lock();
try { try {
if (openedGates.containsKey(thisMapId)) { if (openedGates.containsKey(thisMapId)) {
gateData = openedGates.get(thisMapId); gateData = openedGates.get(thisMapId);
} }
} finally { } finally {
rL.unlock(); readLock.unlock();
} }
if (gateData != null) { if (gateData != null) {
@@ -1349,50 +1340,50 @@ public class EventInstanceManager {
// registers a player status in an event // registers a player status in an event
public final void gridInsert(Character chr, int newStatus) { public final void gridInsert(Character chr, int newStatus) {
wL.lock(); writeLock.lock();
try { try {
playerGrid.put(chr.getId(), newStatus); playerGrid.put(chr.getId(), newStatus);
} finally { } finally {
wL.unlock(); writeLock.unlock();
} }
} }
// unregisters a player status in an event // unregisters a player status in an event
public final void gridRemove(Character chr) { public final void gridRemove(Character chr) {
wL.lock(); writeLock.lock();
try { try {
playerGrid.remove(chr.getId()); playerGrid.remove(chr.getId());
} finally { } finally {
wL.unlock(); writeLock.unlock();
} }
} }
// checks a player status // checks a player status
public final int gridCheck(Character chr) { public final int gridCheck(Character chr) {
rL.lock(); readLock.lock();
try { try {
Integer i = playerGrid.get(chr.getId()); Integer i = playerGrid.get(chr.getId());
return (i != null) ? i : -1; return (i != null) ? i : -1;
} finally { } finally {
rL.unlock(); readLock.unlock();
} }
} }
public final int gridSize() { public final int gridSize() {
rL.lock(); readLock.lock();
try { try {
return playerGrid.size(); return playerGrid.size();
} finally { } finally {
rL.unlock(); readLock.unlock();
} }
} }
public final void gridClear() { public final void gridClear() {
wL.lock(); writeLock.lock();
try { try {
playerGrid.clear(); playerGrid.clear();
} finally { } finally {
wL.unlock(); writeLock.unlock();
} }
} }