Better handle locks for EntityTracker and misc
This commit is contained in:
@@ -2,25 +2,24 @@ package net.minecraft.server;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.googlecode.concurentlocks.ReentrantReadWriteUpdateLock;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
/**
|
||||
* Akarin Changes Note
|
||||
* 1) Add lock for entries set operations (safety issue)
|
||||
* 1) Made collections and entry access thread-safe (safety issue)
|
||||
*/
|
||||
public class EntityTracker {
|
||||
|
||||
private static final Logger a = LogManager.getLogger();
|
||||
private final WorldServer world;
|
||||
private final Set<EntityTrackerEntry> c = Sets.newHashSet();
|
||||
public final ReentrantLock entriesLock = new ReentrantLock(); // Akarin - add lock
|
||||
public final ReentrantReadWriteUpdateLock entriesLock = new ReentrantReadWriteUpdateLock(); // Akarin - add lock
|
||||
public final IntHashMap<EntityTrackerEntry> trackedEntities = new IntHashMap();
|
||||
private int e;
|
||||
|
||||
@@ -38,7 +37,7 @@ public class EntityTracker {
|
||||
this.addEntity(entity, 512, 2);
|
||||
EntityPlayer entityplayer = (EntityPlayer) entity;
|
||||
Iterator iterator = this.c.iterator();
|
||||
entriesLock.lock(); // Akarin
|
||||
// entriesLock.writeLock().lock(); // Akarin - locked in EntityPlayer
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next();
|
||||
@@ -47,7 +46,7 @@ public class EntityTracker {
|
||||
entitytrackerentry.updatePlayer(entityplayer);
|
||||
}
|
||||
}
|
||||
entriesLock.unlock(); // Akarin
|
||||
// entriesLock.writeLock().unlock(); // Akarin - locked in EntityPlayer
|
||||
} else if (entity instanceof EntityFishingHook) {
|
||||
this.addEntity(entity, 64, 5, true);
|
||||
} else if (entity instanceof EntityArrow) {
|
||||
@@ -118,18 +117,18 @@ public class EntityTracker {
|
||||
org.spigotmc.AsyncCatcher.catchOp( "entity track"); // Spigot
|
||||
i = org.spigotmc.TrackingRange.getEntityTrackingRange(entity, i); // Spigot
|
||||
try {
|
||||
// entriesLock.writeLock().lock(); // Akarin - locked from track method
|
||||
if (this.trackedEntities.b(entity.getId())) {
|
||||
throw new IllegalStateException("Entity is already tracked!");
|
||||
}
|
||||
|
||||
EntityTrackerEntry entitytrackerentry = new EntityTrackerEntry(entity, i, this.e, j, flag);
|
||||
|
||||
entriesLock.lock(); // Akarin
|
||||
this.c.add(entitytrackerentry);
|
||||
|
||||
this.trackedEntities.a(entity.getId(), entitytrackerentry);
|
||||
entitytrackerentry.scanPlayers(this.world.players);
|
||||
entriesLock.unlock(); // Akarin
|
||||
// entriesLock.writeLock().unlock(); // Akarin - locked from track method
|
||||
} catch (Throwable throwable) {
|
||||
CrashReport crashreport = CrashReport.a(throwable, "Adding entity to track");
|
||||
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity To Track");
|
||||
@@ -166,34 +165,32 @@ public class EntityTracker {
|
||||
|
||||
public void untrackEntity(Entity entity) {
|
||||
org.spigotmc.AsyncCatcher.catchOp( "entity untrack"); // Spigot
|
||||
entriesLock.writeLock().lock(); // Akarin
|
||||
if (entity instanceof EntityPlayer) {
|
||||
EntityPlayer entityplayer = (EntityPlayer) entity;
|
||||
Iterator iterator = this.c.iterator();
|
||||
entriesLock.lock(); // Akarin
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next();
|
||||
|
||||
entitytrackerentry.a(entityplayer);
|
||||
}
|
||||
entriesLock.unlock(); // Akarin
|
||||
}
|
||||
|
||||
EntityTrackerEntry entitytrackerentry1 = this.trackedEntities.d(entity.getId());
|
||||
|
||||
if (entitytrackerentry1 != null) {
|
||||
entriesLock.lock(); // Akarin
|
||||
this.c.remove(entitytrackerentry1);
|
||||
entitytrackerentry1.a();
|
||||
entriesLock.unlock(); // Akarin
|
||||
}
|
||||
entriesLock.writeLock().unlock(); // Akarin
|
||||
}
|
||||
|
||||
public void updatePlayers() {
|
||||
ArrayList arraylist = Lists.newArrayList();
|
||||
Iterator iterator = this.c.iterator();
|
||||
world.timings.tracker1.startTiming(); // Spigot
|
||||
entriesLock.lock(); // Akarin
|
||||
entriesLock.writeLock().lock(); // Akarin
|
||||
while (iterator.hasNext()) {
|
||||
EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next();
|
||||
|
||||
@@ -221,14 +218,14 @@ public class EntityTracker {
|
||||
}
|
||||
}
|
||||
}
|
||||
entriesLock.unlock(); // Akarin
|
||||
entriesLock.writeLock().unlock(); // Akarin
|
||||
world.timings.tracker2.stopTiming(); // Spigot
|
||||
|
||||
}
|
||||
|
||||
public void a(EntityPlayer entityplayer) {
|
||||
Iterator iterator = this.c.iterator();
|
||||
entriesLock.lock(); // Akarin
|
||||
entriesLock.writeLock().lock(); // Akarin
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next();
|
||||
@@ -239,11 +236,13 @@ public class EntityTracker {
|
||||
entitytrackerentry.updatePlayer(entityplayer);
|
||||
}
|
||||
}
|
||||
entriesLock.unlock(); // Akarin
|
||||
entriesLock.writeLock().unlock(); // Akarin
|
||||
}
|
||||
|
||||
public void a(Entity entity, Packet<?> packet) {
|
||||
entriesLock.readLock().lock(); // Akarin
|
||||
EntityTrackerEntry entitytrackerentry = this.trackedEntities.get(entity.getId());
|
||||
entriesLock.readLock().unlock(); // Akarin
|
||||
|
||||
if (entitytrackerentry != null) {
|
||||
entitytrackerentry.broadcast(packet);
|
||||
@@ -252,7 +251,9 @@ public class EntityTracker {
|
||||
}
|
||||
|
||||
public void sendPacketToEntity(Entity entity, Packet<?> packet) {
|
||||
entriesLock.readLock().lock(); // Akarin
|
||||
EntityTrackerEntry entitytrackerentry = this.trackedEntities.get(entity.getId());
|
||||
entriesLock.readLock().unlock(); // Akarin
|
||||
|
||||
if (entitytrackerentry != null) {
|
||||
entitytrackerentry.broadcastIncludingSelf(packet);
|
||||
@@ -262,21 +263,21 @@ public class EntityTracker {
|
||||
|
||||
public void untrackPlayer(EntityPlayer entityplayer) {
|
||||
Iterator iterator = this.c.iterator();
|
||||
entriesLock.lock(); // Akarin
|
||||
entriesLock.writeLock().lock();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next();
|
||||
|
||||
entitytrackerentry.clear(entityplayer);
|
||||
}
|
||||
entriesLock.unlock(); // Akarin
|
||||
entriesLock.writeLock().unlock();
|
||||
}
|
||||
|
||||
public void a(EntityPlayer entityplayer, Chunk chunk) {
|
||||
ArrayList arraylist = Lists.newArrayList();
|
||||
ArrayList arraylist1 = Lists.newArrayList();
|
||||
Iterator iterator = this.c.iterator();
|
||||
entriesLock.lock(); // Akarin
|
||||
entriesLock.writeLock().lock(); // Akarin
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next();
|
||||
@@ -293,7 +294,7 @@ public class EntityTracker {
|
||||
}
|
||||
}
|
||||
}
|
||||
entriesLock.unlock(); // Akarin
|
||||
entriesLock.writeLock().unlock(); // Akarin
|
||||
|
||||
Entity entity1;
|
||||
|
||||
@@ -320,13 +321,13 @@ public class EntityTracker {
|
||||
public void a(int i) {
|
||||
this.e = (i - 1) * 16;
|
||||
Iterator iterator = this.c.iterator();
|
||||
entriesLock.lock(); // Akarin
|
||||
entriesLock.readLock().lock(); // Akarin
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next();
|
||||
|
||||
entitytrackerentry.a(this.e);
|
||||
}
|
||||
entriesLock.unlock(); // Akarin
|
||||
entriesLock.readLock().unlock(); // Akarin
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user