Fix UUIDIntModifiersMap nested race condition resulting in wrong final value
This commit is contained in:
parent
ff8d2aa5f3
commit
5fdfd9ee2c
@ -15,7 +15,10 @@ class UUIDIntModifiersMap(private val observer: (Int) -> Unit, private val backi
|
|||||||
var value: Int = 0
|
var value: Int = 0
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
private var ignoreRecompute = false
|
||||||
|
|
||||||
fun recompute() {
|
fun recompute() {
|
||||||
|
if (ignoreRecompute) return
|
||||||
var value = 0
|
var value = 0
|
||||||
|
|
||||||
for (mapValue in backingMap.values) {
|
for (mapValue in backingMap.values) {
|
||||||
@ -35,9 +38,15 @@ class UUIDIntModifiersMap(private val observer: (Int) -> Unit, private val backi
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
this.value += value - (old ?: 0)
|
ignoreRecompute = true
|
||||||
observer.invoke(this.value)
|
|
||||||
return true
|
try {
|
||||||
|
this.value += value - (old ?: 0)
|
||||||
|
observer.invoke(this.value)
|
||||||
|
return true
|
||||||
|
} finally {
|
||||||
|
ignoreRecompute = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun get(key: UUID): Int? {
|
operator fun get(key: UUID): Int? {
|
||||||
@ -53,17 +62,29 @@ class UUIDIntModifiersMap(private val observer: (Int) -> Unit, private val backi
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
val old = backingMap.remove(key) ?: return true
|
ignoreRecompute = true
|
||||||
value -= old
|
|
||||||
return true
|
try {
|
||||||
|
val old = backingMap.remove(key) ?: return true
|
||||||
|
value -= old
|
||||||
|
return true
|
||||||
|
} finally {
|
||||||
|
ignoreRecompute = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun clear() {
|
fun clear() {
|
||||||
backingMap.clear()
|
ignoreRecompute = true
|
||||||
val old = this.value
|
|
||||||
this.value = 0
|
try {
|
||||||
if (old != this.value) {
|
backingMap.clear()
|
||||||
observer.invoke(this.value)
|
} finally {
|
||||||
|
ignoreRecompute = false
|
||||||
|
|
||||||
|
if (this.value != 0) {
|
||||||
|
this.value = 0
|
||||||
|
observer.invoke(0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,19 +104,24 @@ class UUIDIntModifiersMap(private val observer: (Int) -> Unit, private val backi
|
|||||||
nbt ?: return
|
nbt ?: return
|
||||||
val old = this.value
|
val old = this.value
|
||||||
this.value = 0
|
this.value = 0
|
||||||
|
ignoreRecompute = true
|
||||||
|
|
||||||
for (value in nbt) {
|
try {
|
||||||
value as CompoundTag
|
for (value in nbt) {
|
||||||
|
value as CompoundTag
|
||||||
|
|
||||||
if (value.contains("key", "value")) {
|
if (value.contains("key", "value")) {
|
||||||
val int = value.getInt("value")
|
val int = value.getInt("value")
|
||||||
backingMap.put(value.getUUID("key"), int)
|
backingMap.put(value.getUUID("key"), int)
|
||||||
this.value += int
|
this.value += int
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (old != this.value) {
|
if (old != this.value) {
|
||||||
observer.invoke(this.value)
|
observer.invoke(this.value)
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
ignoreRecompute = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user