fix bug in CountUpAndDownLatch

This commit is contained in:
Bixilon 2021-07-22 20:04:26 +02:00
parent 8a09f25fe8
commit 4b26398e90
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4

View File

@ -18,21 +18,27 @@ import de.bixilon.minosoft.util.KUtil.toSynchronizedList
class CountUpAndDownLatch @JvmOverloads constructor(count: Int, var parent: CountUpAndDownLatch? = null) { class CountUpAndDownLatch @JvmOverloads constructor(count: Int, var parent: CountUpAndDownLatch? = null) {
private val lock = Object() private val lock = Object()
private val children: MutableSet<CountUpAndDownLatch> = mutableSetOf() private val children: MutableSet<CountUpAndDownLatch> = mutableSetOf()
var count: Int = 0 private var rawCount = 0
set(value) {
val diff = value - field
check(value >= 0) { "Can not set count (previous=$rawCount, value=$value)" }
if (diff > 0) {
total += diff
}
field = value
}
var count: Int
get() { get() {
synchronized(lock) { synchronized(lock) {
return field return rawCount
} }
} }
set(value) { set(value) {
val diff: Int val diff: Int
synchronized(lock) { synchronized(lock) {
diff = value - field diff = value - rawCount
check(value >= 0) { "Can not set count (previous=$field, value=$value)" } rawCount = value
if (diff > 0) {
total += diff
}
field = value
} }
parent?.plus(diff) ?: notify() parent?.plus(diff) ?: notify()
} }
@ -67,8 +73,11 @@ class CountUpAndDownLatch @JvmOverloads constructor(count: Int, var parent: Coun
@JvmOverloads @JvmOverloads
fun await(timeout: Long = 0L) { fun await(timeout: Long = 0L) {
while (count > 0) { while (true) {
synchronized(lock) { synchronized(lock) {
if (rawCount == 0) {
return
}
lock.wait(timeout) lock.wait(timeout)
} }
} }
@ -102,7 +111,10 @@ class CountUpAndDownLatch @JvmOverloads constructor(count: Int, var parent: Coun
} }
fun plus(value: Int): CountUpAndDownLatch { fun plus(value: Int): CountUpAndDownLatch {
count += value synchronized(lock) {
rawCount += value
}
parent?.plus(value) ?: notify()
return this return this
} }