[history] Functionality extracted from some class
This commit is contained in:
commit
be4c578491
@ -0,0 +1,56 @@
|
||||
package ru.landrafhomyak.utility.reference_counter
|
||||
|
||||
import kotlinx.atomicfu.AtomicLong
|
||||
import kotlinx.atomicfu.atomic
|
||||
import kotlinx.atomicfu.update
|
||||
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose1
|
||||
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose2
|
||||
|
||||
internal class CloseableReferenceCounter(private val _errMessage: String) {
|
||||
private val _value: AtomicLong = atomic(0L)
|
||||
|
||||
fun throwClosed() {
|
||||
throw IllegalStateException(this._errMessage)
|
||||
}
|
||||
|
||||
fun incref() {
|
||||
this._value.update { o ->
|
||||
if (o < 0) this.throwClosed()
|
||||
return@update o + 1
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <R> tryIncref(block: () -> R): R {
|
||||
this.incref()
|
||||
return safeAutoClose2(onError = this::decref, action = block)
|
||||
}
|
||||
|
||||
fun checkNotClosed() {
|
||||
if (this._value.value < 0) this.throwClosed()
|
||||
}
|
||||
|
||||
fun decref() {
|
||||
this._value.update(Long::dec)
|
||||
}
|
||||
|
||||
fun close(errExistRefs: String) {
|
||||
val state = this._value.compareAndExchange(0, -1)
|
||||
when {
|
||||
state > 0 -> throw IllegalStateException(errExistRefs)
|
||||
state < 0 -> this.throwClosed()
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <R> withRef(protected: () -> R): R {
|
||||
this.incref()
|
||||
return safeAutoClose1(finally = this::decref, action = protected)
|
||||
}
|
||||
|
||||
private fun AtomicLong.compareAndExchange(expected: Long, newValue: Long): Long {
|
||||
while (true) {
|
||||
val old = this@compareAndExchange.value
|
||||
if (old != expected) return old
|
||||
if (this@compareAndExchange.compareAndSet(old, newValue)) return old
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user