Fix Villagers WeightedList issue (#3860)

dont clone the list for villagers as the list is accessed post sort and needs to have sorted data.
This commit is contained in:
Mariell 2020-07-08 21:57:24 +02:00 committed by GitHub
parent 29453f1dbe
commit e87aa727d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -6,22 +6,75 @@ Subject: [PATCH] Fix Concurrency issue in WeightedList
if multiple threads from worldgen sort at same time, it will crash. if multiple threads from worldgen sort at same time, it will crash.
So make a copy of the list for sorting purposes. So make a copy of the list for sorting purposes.
diff --git a/src/main/java/net/minecraft/server/BehaviorGate.java b/src/main/java/net/minecraft/server/BehaviorGate.java
index 4a5b54b44958b7eddaf2cd7bd517647cca96fd62..46e910581210421c8699637431804dc2f43eb4a6 100644
--- a/src/main/java/net/minecraft/server/BehaviorGate.java
+++ b/src/main/java/net/minecraft/server/BehaviorGate.java
@@ -12,7 +12,7 @@ public class BehaviorGate<E extends EntityLiving> extends Behavior<E> {
private final Set<MemoryModuleType<?>> b;
private final BehaviorGate.Order c;
private final BehaviorGate.Execution d;
- private final WeightedList<Behavior<? super E>> e = new WeightedList<>();
+ private final WeightedList<Behavior<? super E>> e = new WeightedList<>(false); // Paper - don't use a clone
public BehaviorGate(Map<MemoryModuleType<?>, MemoryStatus> map, Set<MemoryModuleType<?>> set, BehaviorGate.Order behaviorgate_order, BehaviorGate.Execution behaviorgate_execution, List<Pair<Behavior<? super E>, Integer>> list) {
super(map);
@@ -60,10 +60,9 @@ public class BehaviorGate<E extends EntityLiving> extends Behavior<E> {
}).forEach((behavior) -> {
behavior.g(worldserver, e0, i);
});
- Set set = this.b;
BehaviorController behaviorcontroller = e0.getBehaviorController();
- set.forEach(behaviorcontroller::removeMemory);
+ this.b.forEach(behaviorcontroller::removeMemory); // Paper - decomp fix
}
@Override
@@ -110,7 +109,7 @@ public class BehaviorGate<E extends EntityLiving> extends Behavior<E> {
private final Consumer<WeightedList<?>> c;
- private Order(Consumer consumer) {
+ private Order(Consumer<WeightedList<?>> consumer) { // Paper - decomp fix
this.c = consumer;
}
diff --git a/src/main/java/net/minecraft/server/WeightedList.java b/src/main/java/net/minecraft/server/WeightedList.java diff --git a/src/main/java/net/minecraft/server/WeightedList.java b/src/main/java/net/minecraft/server/WeightedList.java
index 73e5969b2a15f1639b6285286820e9f7871c7db8..b4e871140e7a0ab5e402e415ea4ff04605157d54 100644 index 73e5969b2a15f1639b6285286820e9f7871c7db8..5d9d58411f2fad9d5da703f964d269b4a7c2b205 100644
--- a/src/main/java/net/minecraft/server/WeightedList.java --- a/src/main/java/net/minecraft/server/WeightedList.java
+++ b/src/main/java/net/minecraft/server/WeightedList.java +++ b/src/main/java/net/minecraft/server/WeightedList.java
@@ -14,7 +14,7 @@ import java.util.stream.Stream; @@ -6,7 +6,7 @@ import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.Dynamic;
import com.mojang.serialization.DynamicOps;
-import com.mojang.serialization.OptionalDynamic;
+
import java.util.Comparator;
import java.util.List;
import java.util.Random;
@@ -14,26 +14,32 @@ import java.util.stream.Stream;
public class WeightedList<U> { public class WeightedList<U> {
- protected final List<WeightedList.a<U>> a; - protected final List<WeightedList.a<U>> a;
+ protected final List<WeightedList.a<U>> list; // Paper - decompile conflict + protected final List<WeightedList.a<U>> list; // Paper - decompile conflict
private final Random b; private final Random b;
+ private final boolean isUnsafe; // Paper
public WeightedList() { - public WeightedList() {
@@ -23,17 +23,17 @@ public class WeightedList<U> { - this(Lists.newArrayList());
+ // Paper start - add useClone option
+ public WeightedList() { this(true); }
+ public WeightedList(boolean isUnsafe) {
+ this(Lists.newArrayList(), isUnsafe);
}
private WeightedList(List<WeightedList.a<U>> list) { - private WeightedList(List<WeightedList.a<U>> list) {
+ private WeightedList(List<WeightedList.a<U>> list) { this(list, true); }
+ private WeightedList(List<WeightedList.a<U>> list, boolean isUnsafe) {
+ this.isUnsafe = isUnsafe;
+ // Paper end
this.b = new Random(); this.b = new Random();
- this.a = Lists.newArrayList(list); - this.a = Lists.newArrayList(list);
+ this.list = Lists.newArrayList(list); // Paper - decompile conflict + this.list = Lists.newArrayList(list); // Paper - decompile conflict
@ -41,7 +94,7 @@ index 73e5969b2a15f1639b6285286820e9f7871c7db8..b4e871140e7a0ab5e402e415ea4ff046
return this; return this;
} }
@@ -42,21 +42,20 @@ public class WeightedList<U> { @@ -42,21 +48,20 @@ public class WeightedList<U> {
} }
public WeightedList<U> a(Random random) { public WeightedList<U> a(Random random) {
@ -53,10 +106,10 @@ index 73e5969b2a15f1639b6285286820e9f7871c7db8..b4e871140e7a0ab5e402e415ea4ff046
- })); - }));
- return this; - return this;
+ // Paper start - make concurrent safe, work off a clone of the list + // Paper start - make concurrent safe, work off a clone of the list
+ java.util.ArrayList<WeightedList.a<U>> list = new java.util.ArrayList<WeightedList.a<U>>(this.list); + List<WeightedList.a<U>> list = isUnsafe ? new java.util.ArrayList<WeightedList.a<U>>(this.list) : this.list;
+ list.forEach((weightedlist_a) -> weightedlist_a.a(random.nextFloat())); + list.forEach((weightedlist_a) -> weightedlist_a.a(random.nextFloat()));
+ list.sort(Comparator.comparingDouble(a::c)); + list.sort(Comparator.comparingDouble(a::c));
+ return new WeightedList<>(list); + return isUnsafe ? new WeightedList<>(list, isUnsafe) : this;
+ // Paper end + // Paper end
} }
@ -71,7 +124,7 @@ index 73e5969b2a15f1639b6285286820e9f7871c7db8..b4e871140e7a0ab5e402e415ea4ff046
} }
public U b(Random random) { public U b(Random random) {
@@ -64,7 +63,7 @@ public class WeightedList<U> { @@ -64,7 +69,7 @@ public class WeightedList<U> {
} }
public String toString() { public String toString() {
@ -80,7 +133,7 @@ index 73e5969b2a15f1639b6285286820e9f7871c7db8..b4e871140e7a0ab5e402e415ea4ff046
} }
public static class a<T> { public static class a<T> {
@@ -98,11 +97,7 @@ public class WeightedList<U> { @@ -98,11 +103,7 @@ public class WeightedList<U> {
return new Codec<WeightedList.a<E>>() { return new Codec<WeightedList.a<E>>() {
public <T> DataResult<Pair<WeightedList.a<E>, T>> decode(DynamicOps<T> dynamicops, T t0) { public <T> DataResult<Pair<WeightedList.a<E>, T>> decode(DynamicOps<T> dynamicops, T t0) {
Dynamic<T> dynamic = new Dynamic(dynamicops, t0); Dynamic<T> dynamic = new Dynamic(dynamicops, t0);