From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Aikar Date: Fri, 29 May 2020 20:29:02 -0400 Subject: [PATCH] Synchronize PalettedContainer instead of ReentrantLock Mojang has flaws in their logic about chunks being concurrently wrote to. So we constantly see crashes around multiple threads writing. Additionally, java has optimized synchronization so well that its in many times faster than trying to manage read wrote locks for low contention situations. And this is extremely a low contention situation. diff --git a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java index 5ac948b5b82f3144cdf402af440251cb8c7369d7..d8b7a7d9aa3ef47aa4e222c6ca85e83ce21f2444 100644 --- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java +++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java @@ -36,16 +36,18 @@ public class PalettedContainer implements PaletteResize { private final DebugBuffer> traces = null; public void acquire() { + /* // Paper start - disable this - use proper synchronization if (this.traces != null) { Thread thread = Thread.currentThread(); this.traces.push(Pair.of(thread, thread.getStackTrace())); } ThreadingDetector.checkAndLock(this.lock, this.traces, "PalettedContainer"); + */ // Paper end } public void release() { - this.lock.release(); + //this.lock.release(); // Paper - disable this } public PalettedContainer(Palette fallbackPalette, IdMapper idList, Function elementDeserializer, Function elementSerializer, T defaultElement) { @@ -96,7 +98,7 @@ public class PalettedContainer implements PaletteResize { return this.palette.idFor(objectAdded); } - public T getAndSet(int x, int y, int z, T value) { + public synchronized T getAndSet(int x, int y, int z, T value) { // Paper - synchronize Object var6; try { this.acquire(); @@ -120,7 +122,7 @@ public class PalettedContainer implements PaletteResize { return (T)(object == null ? this.defaultValue : object); } - public void set(int i, int j, int k, T object) { + public synchronized void set(int i, int j, int k, T object) { // Paper - synchronize try { this.acquire(); this.set(getIndex(i, j, k), object); @@ -144,7 +146,7 @@ public class PalettedContainer implements PaletteResize { return (T)(object == null ? this.defaultValue : object); } - public void read(FriendlyByteBuf buf) { + public synchronized void read(FriendlyByteBuf buf) { // Paper - synchronize try { this.acquire(); int i = buf.readByte(); @@ -161,7 +163,7 @@ public class PalettedContainer implements PaletteResize { } public void writeDataPaletteBlock(FriendlyByteBuf packetDataSerializer) { this.write(packetDataSerializer); } // Paper - OBFHELPER - public void write(FriendlyByteBuf buf) { + public synchronized void write(FriendlyByteBuf buf) { // Paper - synchronize try { this.acquire(); buf.writeByte(this.bits); @@ -173,7 +175,7 @@ public class PalettedContainer implements PaletteResize { } - public void read(ListTag paletteNbt, long[] data) { + public synchronized void read(ListTag paletteNbt, long[] data) { // Paper - synchronize try { this.acquire(); int i = Math.max(4, Mth.ceillog2(paletteNbt.size())); @@ -206,7 +208,7 @@ public class PalettedContainer implements PaletteResize { } - public void write(CompoundTag nbt, String paletteKey, String dataKey) { + public synchronized void write(CompoundTag nbt, String paletteKey, String dataKey) { // Paper - synchronize try { this.acquire(); HashMapPalette hashMapPalette = new HashMapPalette<>(this.registry, this.bits, this.dummyPaletteResize, this.reader, this.writer);