spigot/CraftBukkit-Patches/0101-Remove-DataWatcher-Locking.patch
2020-01-22 08:00:00 +11:00

140 lines
5.3 KiB
Diff

From bb3ede9f94fb1808ed7b1e6c73844861fa65d471 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Tue, 9 Jul 2019 02:18:54 -0700
Subject: [PATCH] Remove DataWatcher Locking
The lock in DataWatcher is used to prevent concurrent modifications,
however any modifications to this map only occur on initialization of
an Entity in its constructor.
Every other access is through a readlock, which allows the threads to
pass if there is no thread holding the writelock.
Since the writelock is only obtained in the constructor of the Entity,
the further readlocks are actually useless.
This patch also changes the entries map to be fastutil
int2objectopenhashmap for performance.
diff --git a/src/main/java/net/minecraft/server/DataWatcher.java b/src/main/java/net/minecraft/server/DataWatcher.java
index 211b8beaf..be8e705fc 100644
--- a/src/main/java/net/minecraft/server/DataWatcher.java
+++ b/src/main/java/net/minecraft/server/DataWatcher.java
@@ -21,8 +21,8 @@ public class DataWatcher {
private static final Logger LOGGER = LogManager.getLogger();
private static final Map<Class<? extends Entity>, Integer> b = Maps.newHashMap();
private final Entity entity;
- private final Map<Integer, DataWatcher.Item<?>> entries = Maps.newHashMap();
- private final ReadWriteLock lock = new ReentrantReadWriteLock();
+ private final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<DataWatcher.Item<?>> entries = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(); // Spigot - use better map // PAIL
+ // private final ReadWriteLock lock = new ReentrantReadWriteLock(); // Spigot - not required
private boolean f = true;
private boolean g;
@@ -70,7 +70,9 @@ public class DataWatcher {
}
}
+ boolean registrationLocked; // Spigot
public <T> void register(DataWatcherObject<T> datawatcherobject, T t0) {
+ if (this.registrationLocked) throw new IllegalStateException("Registering datawatcher object after entity initialization"); // Spigot
int i = datawatcherobject.a();
if (i > 254) {
@@ -87,13 +89,15 @@ public class DataWatcher {
private <T> void registerObject(DataWatcherObject<T> datawatcherobject, T t0) {
DataWatcher.Item<T> datawatcher_item = new DataWatcher.Item<>(datawatcherobject, t0);
- this.lock.writeLock().lock();
+ // this.lock.writeLock().lock(); // Spigot - not required
this.entries.put(datawatcherobject.a(), datawatcher_item);
this.f = false;
- this.lock.writeLock().unlock();
+ // this.lock.writeLock().unlock(); // Spigot - not required
}
private <T> DataWatcher.Item<T> b(DataWatcherObject<T> datawatcherobject) {
+ // Spigot start
+ /*
this.lock.readLock().lock();
DataWatcher.Item datawatcher_item;
@@ -111,6 +115,9 @@ public class DataWatcher {
}
return datawatcher_item;
+ */
+ return (DataWatcher.Item) this.entries.get(datawatcherobject.a());
+ // Spigot end
}
public <T> T get(DataWatcherObject<T> datawatcherobject) {
@@ -157,7 +164,7 @@ public class DataWatcher {
List<DataWatcher.Item<?>> list = null;
if (this.g) {
- this.lock.readLock().lock();
+ // this.lock.readLock().lock(); // Spigot - not required
Iterator iterator = this.entries.values().iterator();
while (iterator.hasNext()) {
@@ -173,7 +180,7 @@ public class DataWatcher {
}
}
- this.lock.readLock().unlock();
+ // this.lock.readLock().unlock(); // Spigot - not required
}
this.g = false;
@@ -184,7 +191,7 @@ public class DataWatcher {
public List<DataWatcher.Item<?>> c() {
List<DataWatcher.Item<?>> list = null;
- this.lock.readLock().lock();
+ // this.lock.readLock().lock(); // Spigot - not required
DataWatcher.Item datawatcher_item;
@@ -195,7 +202,7 @@ public class DataWatcher {
}
}
- this.lock.readLock().unlock();
+ // this.lock.readLock().unlock(); // Spigot - not required
return list;
}
@@ -246,7 +253,7 @@ public class DataWatcher {
public void e() {
this.g = false;
- this.lock.readLock().lock();
+ // this.lock.readLock().lock(); // Spigot - not required
Iterator iterator = this.entries.values().iterator();
while (iterator.hasNext()) {
@@ -255,7 +262,7 @@ public class DataWatcher {
datawatcher_item.a(false);
}
- this.lock.readLock().unlock();
+ // this.lock.readLock().unlock(); // Spigot - not required
}
public static class Item<T> {
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 3fa90cc91..4c802459d 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -220,6 +220,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener {
this.datawatcher.register(Entity.aC, false);
this.datawatcher.register(Entity.POSE, EntityPose.STANDING);
this.initDatawatcher();
+ this.datawatcher.registrationLocked = true; // Spigot
this.headHeight = this.getHeadHeight(EntityPose.STANDING, this.size);
}
--
2.20.1