65 lines
1.8 KiB
Kotlin
65 lines
1.8 KiB
Kotlin
@file:OptIn(ExperimentalContracts::class)
|
|
|
|
package ru.landgrafhomyak.utility.closeable_state
|
|
|
|
import kotlin.contracts.ExperimentalContracts
|
|
import ru.landgrafhomyak.utility.closeable_state.internal.AtomicLong
|
|
import ru.landgrafhomyak.utility.closeable_state.internal.Misc
|
|
import ru.landgrafhomyak.utility.closeable_state.internal.compareAndExchange
|
|
import ru.landgrafhomyak.utility.closeable_state.internal.get
|
|
import ru.landgrafhomyak.utility.closeable_state.internal.newAtomicLong
|
|
import ru.landgrafhomyak.utility.closeable_state.internal.update
|
|
|
|
public open class UsagesCounter : CloseableState.AllowsConcurrency {
|
|
private val _value: AtomicLong = newAtomicLong(0L)
|
|
|
|
public constructor()
|
|
|
|
public fun getCurrentUsagesCount(): Long = this._value.get()
|
|
|
|
public open override fun throwClosed(): Nothing {
|
|
throw IllegalStateException("Object is closed")
|
|
}
|
|
|
|
public open override fun throwInUse(): Nothing {
|
|
throw IllegalStateException("Failed close object because it is in use")
|
|
}
|
|
|
|
|
|
public final override val isClosed: Boolean get() = this._value.get() < 0
|
|
|
|
public final override fun assertNotClosed() {
|
|
if (this._value.get() < 0) this.throwClosed()
|
|
}
|
|
|
|
@ManualStateManipulation
|
|
public final override fun startUsage() {
|
|
this._value.update { o ->
|
|
if (o < 0) this.throwClosed()
|
|
return@update o + 1
|
|
}
|
|
}
|
|
|
|
@ManualStateManipulation
|
|
public final override fun finishUsage() {
|
|
this._value.update(Long::dec)
|
|
}
|
|
|
|
@ManualStateManipulation
|
|
public final override fun close() {
|
|
val state = this._value.compareAndExchange(0, Misc.CLOSED_STATE_VALUE)
|
|
when {
|
|
state > 0 -> this.throwInUse()
|
|
state < 0 -> this.throwClosed()
|
|
}
|
|
}
|
|
|
|
override fun toString(): String {
|
|
val cached = this._value.get()
|
|
@Suppress("LiftReturnOrAssignment")
|
|
if (cached < 0)
|
|
return "<closeable usages counter [closed]>"
|
|
else
|
|
return "<closeable usages counter [${cached}]>"
|
|
}
|
|
} |