mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-25 18:09:17 +00:00
Fix race condition in IteratorSafeOrderedReferenceSet (#278)
* Fix race condition in IteratorSafeOrderedReferenceSet * Use cached firstInvalidIndex at the beginning of the method
This commit is contained in:
@@ -23,7 +23,7 @@ and, in my opinion, worth the low risk of minor mob-spawning-related
|
||||
inconsistencies.
|
||||
|
||||
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/IteratorSafeOrderedReferenceSet.java b/src/main/java/ca/spottedleaf/moonrise/common/list/IteratorSafeOrderedReferenceSet.java
|
||||
index c21e00812f1aaa1279834a0562d360d6b89e146c..4ae478c04ef44c91408a7f3f0405291f91794873 100644
|
||||
index c21e00812f1aaa1279834a0562d360d6b89e146c..19e0bf50cf8863f42ce19c3d0d8911c0c9b8ad4a 100644
|
||||
--- a/src/main/java/ca/spottedleaf/moonrise/common/list/IteratorSafeOrderedReferenceSet.java
|
||||
+++ b/src/main/java/ca/spottedleaf/moonrise/common/list/IteratorSafeOrderedReferenceSet.java
|
||||
@@ -10,7 +10,7 @@ public final class IteratorSafeOrderedReferenceSet<E> {
|
||||
@@ -31,7 +31,7 @@ index c21e00812f1aaa1279834a0562d360d6b89e146c..4ae478c04ef44c91408a7f3f0405291f
|
||||
|
||||
private final Reference2IntLinkedOpenHashMap<E> indexMap;
|
||||
- private int firstInvalidIndex = -1;
|
||||
+ private volatile int firstInvalidIndex = -1; // Leaf - Async mob spawning - volatile
|
||||
+ private final java.util.concurrent.atomic.AtomicInteger firstInvalidIndex = new java.util.concurrent.atomic.AtomicInteger(-1); // Leaf - Pufferfish - Async mob spawning - atomic
|
||||
|
||||
/* list impl */
|
||||
private E[] listElements;
|
||||
@@ -44,7 +44,22 @@ index c21e00812f1aaa1279834a0562d360d6b89e146c..4ae478c04ef44c91408a7f3f0405291f
|
||||
|
||||
public IteratorSafeOrderedReferenceSet() {
|
||||
this(16, 0.75f, 16, 0.2);
|
||||
@@ -79,7 +79,7 @@ public final class IteratorSafeOrderedReferenceSet<E> {
|
||||
@@ -74,16 +74,26 @@ public final class IteratorSafeOrderedReferenceSet<E> {
|
||||
}
|
||||
*/
|
||||
|
||||
+ // Pufferfish start - async mob spawning
|
||||
+ // TODO: backup plan if the issue persists, don't run
|
||||
+ // this.set.finishRawIterator() or defrag() off-main
|
||||
+ /*
|
||||
+ protected final boolean allowSafeIteration() {
|
||||
+ return ca.spottedleaf.moonrise.common.util.TickThread.isTickThread();
|
||||
+ }
|
||||
+ */
|
||||
+ // Pufferfish end - async mob spawning
|
||||
+
|
||||
private double getFragFactor() {
|
||||
return 1.0 - ((double)this.indexMap.size() / (double)this.listSize);
|
||||
}
|
||||
|
||||
public int createRawIterator() {
|
||||
@@ -53,7 +68,12 @@ index c21e00812f1aaa1279834a0562d360d6b89e146c..4ae478c04ef44c91408a7f3f0405291f
|
||||
if (this.indexMap.isEmpty()) {
|
||||
return -1;
|
||||
} else {
|
||||
@@ -100,7 +100,7 @@ public final class IteratorSafeOrderedReferenceSet<E> {
|
||||
- return this.firstInvalidIndex == 0 ? this.indexMap.getInt(this.indexMap.firstKey()) : 0;
|
||||
+ return this.firstInvalidIndex.get() == 0 ? this.indexMap.getInt(this.indexMap.firstKey()) : 0; // Leaf - Pufferfish - Async mob spawning
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +110,7 @@ public final class IteratorSafeOrderedReferenceSet<E> {
|
||||
}
|
||||
|
||||
public void finishRawIterator() {
|
||||
@@ -62,7 +82,19 @@ index c21e00812f1aaa1279834a0562d360d6b89e146c..4ae478c04ef44c91408a7f3f0405291f
|
||||
if (this.getFragFactor() >= this.maxFragFactor) {
|
||||
this.defrag();
|
||||
}
|
||||
@@ -117,7 +117,7 @@ public final class IteratorSafeOrderedReferenceSet<E> {
|
||||
@@ -110,14 +120,17 @@ public final class IteratorSafeOrderedReferenceSet<E> {
|
||||
public boolean remove(final E element) {
|
||||
final int index = this.indexMap.removeInt(element);
|
||||
if (index >= 0) {
|
||||
- if (this.firstInvalidIndex < 0 || index < this.firstInvalidIndex) {
|
||||
- this.firstInvalidIndex = index;
|
||||
+ // Leaf start - Pufferfish - Async mob spawning
|
||||
+ int firstInvalidIndex = this.firstInvalidIndex.get();
|
||||
+ if (firstInvalidIndex < 0 || index < firstInvalidIndex) {
|
||||
+ this.firstInvalidIndex.set(index);
|
||||
}
|
||||
+ // Leaf end - Pufferfish - Async mob spawning
|
||||
if (this.listElements[index] != element) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
this.listElements[index] = null;
|
||||
@@ -71,7 +103,50 @@ index c21e00812f1aaa1279834a0562d360d6b89e146c..4ae478c04ef44c91408a7f3f0405291f
|
||||
this.defrag();
|
||||
}
|
||||
//this.check();
|
||||
@@ -219,7 +219,7 @@ public final class IteratorSafeOrderedReferenceSet<E> {
|
||||
@@ -149,14 +162,17 @@ public final class IteratorSafeOrderedReferenceSet<E> {
|
||||
}
|
||||
|
||||
private void defrag() {
|
||||
- if (this.firstInvalidIndex < 0) {
|
||||
+ // Leaf start - Pufferfish - Async mob spawning
|
||||
+ int firstInvalidIndex = this.firstInvalidIndex.get();
|
||||
+ if (firstInvalidIndex < 0) {
|
||||
return; // nothing to do
|
||||
}
|
||||
+ // Leaf end - Pufferfish - Async mob spawning
|
||||
|
||||
if (this.indexMap.isEmpty()) {
|
||||
Arrays.fill(this.listElements, 0, this.listSize, null);
|
||||
this.listSize = 0;
|
||||
- this.firstInvalidIndex = -1;
|
||||
+ this.firstInvalidIndex.set(-1); // Leaf - Pufferfish - Async mob spawning
|
||||
//this.check();
|
||||
return;
|
||||
}
|
||||
@@ -166,11 +182,11 @@ public final class IteratorSafeOrderedReferenceSet<E> {
|
||||
int lastValidIndex;
|
||||
java.util.Iterator<Reference2IntMap.Entry<E>> iterator;
|
||||
|
||||
- if (this.firstInvalidIndex == 0) {
|
||||
+ if (firstInvalidIndex == 0) { // Leaf - Pufferfish - Async mob spawning
|
||||
iterator = this.indexMap.reference2IntEntrySet().fastIterator();
|
||||
lastValidIndex = 0;
|
||||
} else {
|
||||
- lastValidIndex = this.firstInvalidIndex;
|
||||
+ lastValidIndex = firstInvalidIndex; // Leaf - Pufferfish - Async mob spawning
|
||||
final E key = backingArray[lastValidIndex - 1];
|
||||
iterator = this.indexMap.reference2IntEntrySet().fastIterator(new Reference2IntMap.Entry<E>() {
|
||||
@Override
|
||||
@@ -201,7 +217,7 @@ public final class IteratorSafeOrderedReferenceSet<E> {
|
||||
// cleanup end
|
||||
Arrays.fill(backingArray, lastValidIndex, this.listSize, null);
|
||||
this.listSize = lastValidIndex;
|
||||
- this.firstInvalidIndex = -1;
|
||||
+ this.firstInvalidIndex.set(-1); // Leaf - Pufferfish - Async mob spawning
|
||||
//this.check();
|
||||
}
|
||||
|
||||
@@ -219,7 +235,7 @@ public final class IteratorSafeOrderedReferenceSet<E> {
|
||||
}
|
||||
|
||||
public IteratorSafeOrderedReferenceSet.Iterator<E> iterator(final int flags) {
|
||||
@@ -80,3 +155,12 @@ index c21e00812f1aaa1279834a0562d360d6b89e146c..4ae478c04ef44c91408a7f3f0405291f
|
||||
return new BaseIterator<>(this, true, (flags & ITERATOR_FLAG_SEE_ADDITIONS) != 0 ? Integer.MAX_VALUE : this.listSize);
|
||||
}
|
||||
|
||||
@@ -306,7 +322,7 @@ public final class IteratorSafeOrderedReferenceSet<E> {
|
||||
}
|
||||
this.lastReturned = null;
|
||||
this.finished = true;
|
||||
- this.set.finishRawIterator();
|
||||
+ this.set.finishRawIterator(); // Pufferfish - async mob spawning - diff on change
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user