Removed excess atomic functions and minor fixes
This commit is contained in:
parent
999ff63ccf
commit
7131a38bd4
@ -0,0 +1,5 @@
|
|||||||
|
package ru.landgrafhomyak.utility.closeable_state_1
|
||||||
|
|
||||||
|
internal object _MiscMultiplatform {
|
||||||
|
internal const val CLOSED_STATE_VALUE = -0x4000_0000_0000_0000L
|
||||||
|
}
|
||||||
@ -1,27 +0,0 @@
|
|||||||
@file:JvmName("AtomicsKt")
|
|
||||||
|
|
||||||
package ru.landgrafhomyak.utility.closeable_state_1.internal
|
|
||||||
|
|
||||||
import kotlin.jvm.JvmName
|
|
||||||
|
|
||||||
|
|
||||||
internal expect class AtomicLong
|
|
||||||
internal expect class AtomicReference<T>
|
|
||||||
|
|
||||||
internal expect inline fun newAtomicLong(initial: Long): AtomicLong
|
|
||||||
internal expect inline fun <T> newAtomicRef(initial: T): AtomicReference<T>
|
|
||||||
|
|
||||||
internal expect inline fun AtomicLong.get(): Long
|
|
||||||
internal expect inline fun <T> AtomicReference<T>.get(): T
|
|
||||||
|
|
||||||
internal expect inline fun AtomicLong.update(operator: (Long) -> Long)
|
|
||||||
internal expect inline fun <T> AtomicReference<T>.update(operator: (T) -> T)
|
|
||||||
|
|
||||||
internal expect inline fun AtomicLong.getAndUpdate(operator: (Long) -> Long): Long
|
|
||||||
internal expect inline fun <T> AtomicReference<T>.getAndUpdate(operator: (T) -> T): T
|
|
||||||
|
|
||||||
internal expect inline fun AtomicLong.compareAndSet(expected: Long, newValue: Long): Boolean
|
|
||||||
internal expect inline fun <T> AtomicReference<T>.compareAndSet(expected: T, newValue: T): Boolean
|
|
||||||
|
|
||||||
internal expect inline fun AtomicLong.compareAndExchange(expected: Long, newValue: Long): Long
|
|
||||||
internal expect inline fun <T> AtomicReference<T>.compareAndExchange(expected: T, newValue: T): T
|
|
||||||
@ -13,7 +13,7 @@ public /* open */ class jErrorOnConcurrentAccessState
|
|||||||
private final AtomicReference<State> _currentState;
|
private final AtomicReference<State> _currentState;
|
||||||
|
|
||||||
public jErrorOnConcurrentAccessState() {
|
public jErrorOnConcurrentAccessState() {
|
||||||
this._currentState = new AtomicReference<>();
|
this._currentState = new AtomicReference<>(State.OPEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -74,7 +74,7 @@ public /* open */ class jErrorOnConcurrentAccessState
|
|||||||
case IN_USE:
|
case IN_USE:
|
||||||
return "<closeable error-on-concurrent-access state [in use]>";
|
return "<closeable error-on-concurrent-access state [in use]>";
|
||||||
case OPEN:
|
case OPEN:
|
||||||
return "<closeable error-on-concurrent-access state [close]>";
|
return "<closeable error-on-concurrent-access state [closed]>";
|
||||||
}
|
}
|
||||||
throw new RuntimeException("Unreachable");
|
throw new RuntimeException("Unreachable");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
package ru.landgrafhomyak.utility.closeable_state_1;
|
package ru.landgrafhomyak.utility.closeable_state_1;
|
||||||
|
|
||||||
import ru.landgrafhomyak.utility.closeable_state_1.internal.Misc;
|
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
public /* open */ class jUsagesCounter extends jUsagesCounter$Errors implements CloseableState.AllowsConcurrency {
|
public /* open */ class jUsagesCounter
|
||||||
|
extends jUsagesCounter$Errors
|
||||||
|
implements CloseableState.AllowsConcurrency {
|
||||||
private final AtomicLong _currentUsagesCount;
|
private final AtomicLong _currentUsagesCount;
|
||||||
|
|
||||||
public jUsagesCounter() {
|
public jUsagesCounter() {
|
||||||
@ -56,7 +56,7 @@ public /* open */ class jUsagesCounter extends jUsagesCounter$Errors implements
|
|||||||
while (true) {
|
while (true) {
|
||||||
currentReferencesCount = this._currentUsagesCount.get();
|
currentReferencesCount = this._currentUsagesCount.get();
|
||||||
if (currentReferencesCount != 0) break;
|
if (currentReferencesCount != 0) break;
|
||||||
if (this._currentUsagesCount.compareAndSet(currentReferencesCount, Misc.CLOSED_STATE_VALUE))
|
if (this._currentUsagesCount.compareAndSet(currentReferencesCount, _MiscMultiplatform.CLOSED_STATE_VALUE))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,124 +0,0 @@
|
|||||||
@file:Suppress("USELESS_CAST", "NOTHING_TO_INLINE")
|
|
||||||
@file:JvmName("AtomicsKt")
|
|
||||||
|
|
||||||
package ru.landgrafhomyak.utility.closeable_state_1.internal
|
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicLong as jAtomicLong
|
|
||||||
import java.util.concurrent.atomic.AtomicReference as jAtomicReference
|
|
||||||
import kotlin.jvm.JvmName
|
|
||||||
|
|
||||||
|
|
||||||
internal actual typealias AtomicLong = jAtomicLong
|
|
||||||
internal actual typealias AtomicReference<T> = jAtomicReference<T>
|
|
||||||
|
|
||||||
|
|
||||||
internal actual inline fun newAtomicLong(initial: Long): AtomicLong =
|
|
||||||
jAtomicLong(initial)
|
|
||||||
|
|
||||||
internal actual inline fun <T> newAtomicRef(initial: T): AtomicReference<T> =
|
|
||||||
jAtomicReference(initial)
|
|
||||||
|
|
||||||
|
|
||||||
internal actual inline fun AtomicLong.get(): Long =
|
|
||||||
(this as jAtomicLong).get()
|
|
||||||
|
|
||||||
internal actual inline fun <T> AtomicReference<T>.get(): T =
|
|
||||||
(this as jAtomicReference).get()
|
|
||||||
|
|
||||||
|
|
||||||
internal actual inline fun AtomicLong.update(operator: (Long) -> Long) {
|
|
||||||
val a = (this as jAtomicLong)
|
|
||||||
Misc._getAndUpdate(
|
|
||||||
get = a::get,
|
|
||||||
cas = a::compareAndSet,
|
|
||||||
operator = operator
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal actual inline fun <T> AtomicReference<T>.update(operator: (T) -> T) {
|
|
||||||
val a = (this as jAtomicReference)
|
|
||||||
Misc._getAndUpdate(
|
|
||||||
get = a::get,
|
|
||||||
cas = a::compareAndSet,
|
|
||||||
operator = operator
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal actual inline fun AtomicLong.getAndUpdate(operator: (Long) -> Long): Long {
|
|
||||||
val a = (this as jAtomicLong)
|
|
||||||
return Misc._getAndUpdate(
|
|
||||||
get = a::get,
|
|
||||||
cas = a::compareAndSet,
|
|
||||||
operator = operator
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal actual inline fun <T> AtomicReference<T>.getAndUpdate(operator: (T) -> T): T {
|
|
||||||
val a = (this as jAtomicReference)
|
|
||||||
return Misc._getAndUpdate(
|
|
||||||
get = a::get,
|
|
||||||
cas = a::compareAndSet,
|
|
||||||
operator = operator
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
internal actual inline fun AtomicLong.compareAndSet(expected: Long, newValue: Long): Boolean =
|
|
||||||
(this as jAtomicLong).compareAndSet(expected, newValue)
|
|
||||||
|
|
||||||
internal actual inline fun <T> AtomicReference<T>.compareAndSet(expected: T, newValue: T): Boolean =
|
|
||||||
(this as jAtomicReference).compareAndSet(expected, newValue)
|
|
||||||
|
|
||||||
|
|
||||||
private fun AtomicLong.`compareAndExchange$custom`(expected: Long, newValue: Long): Long {
|
|
||||||
val a = (this as jAtomicLong)
|
|
||||||
return Misc._compareAndExchange(
|
|
||||||
get = a::get,
|
|
||||||
cas = a::compareAndSet,
|
|
||||||
expected = expected, newValue = newValue
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun <T> AtomicReference<T>.`compareAndExchange$custom`(expected: T, newValue: T): T {
|
|
||||||
val a = (this as jAtomicReference)
|
|
||||||
return Misc._compareAndExchange(
|
|
||||||
get = a::get,
|
|
||||||
cas = a::compareAndSet,
|
|
||||||
expected = expected, newValue = newValue
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal actual inline fun AtomicLong.compareAndExchange(expected: Long, newValue: Long): Long {
|
|
||||||
if (_long_isNativeCompareAndExchangeExists)
|
|
||||||
return (this as jAtomicLong).compareAndExchange(expected, newValue)
|
|
||||||
else
|
|
||||||
return this.`compareAndExchange$custom`(expected, newValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal actual inline fun <T> AtomicReference<T>.compareAndExchange(expected: T, newValue: T): T {
|
|
||||||
if (_ref_isNativeCompareAndExchangeExists)
|
|
||||||
return (this as jAtomicReference).compareAndExchange(expected, newValue)
|
|
||||||
else
|
|
||||||
return this.`compareAndExchange$custom`(expected, newValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val _long_isNativeCompareAndExchangeExists = run {
|
|
||||||
val a = jAtomicLong()
|
|
||||||
try {
|
|
||||||
a.compareAndExchange(0, 0)
|
|
||||||
return@run true
|
|
||||||
} catch (_: NoSuchMethodError) {
|
|
||||||
return@run false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val _ref_isNativeCompareAndExchangeExists = run {
|
|
||||||
val a = jAtomicReference<Nothing?>()
|
|
||||||
try {
|
|
||||||
a.compareAndExchange(null, null)
|
|
||||||
return@run true
|
|
||||||
} catch (_: NoSuchMethodError) {
|
|
||||||
return@run false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +1,17 @@
|
|||||||
package ru.landgrafhomyak.utility.closeable_state_1
|
package ru.landgrafhomyak.utility.closeable_state_1
|
||||||
|
|
||||||
import ru.landgrafhomyak.utility.closeable_state_1.internal.compareAndExchange
|
import kotlinx.atomicfu.atomic
|
||||||
import ru.landgrafhomyak.utility.closeable_state_1.internal.get
|
import ru.landgrafhomyak.utility.closeable_state_1._MiscNonJvm.compareAndExchange
|
||||||
import ru.landgrafhomyak.utility.closeable_state_1.internal.newAtomicRef
|
|
||||||
|
|
||||||
public actual open class ErrorOnConcurrentAccessState : CloseableState.ExternallySynchronized {
|
public actual open class ErrorOnConcurrentAccessState : CloseableState.ExternallySynchronized {
|
||||||
private enum class State {
|
private enum class State {
|
||||||
OPEN, IN_USE, CLOSED
|
OPEN, IN_USE, CLOSED
|
||||||
}
|
}
|
||||||
|
|
||||||
private val _state = newAtomicRef(State.OPEN)
|
private val _state = atomic(State.OPEN)
|
||||||
|
|
||||||
public actual final override val isInUse: Boolean
|
public actual final override val isInUse: Boolean
|
||||||
get() = this._state.get() === State.IN_USE
|
get() = this._state.value === State.IN_USE
|
||||||
|
|
||||||
protected actual open fun throwClosed(): Nothing {
|
protected actual open fun throwClosed(): Nothing {
|
||||||
throw IllegalStateException("Object is closed")
|
throw IllegalStateException("Object is closed")
|
||||||
@ -27,12 +26,12 @@ public actual open class ErrorOnConcurrentAccessState : CloseableState.Externall
|
|||||||
}
|
}
|
||||||
|
|
||||||
public actual final override fun assertNotClosed() {
|
public actual final override fun assertNotClosed() {
|
||||||
if (this._state.get() === State.CLOSED)
|
if (this._state.value === State.CLOSED)
|
||||||
this.throwClosed()
|
this.throwClosed()
|
||||||
}
|
}
|
||||||
|
|
||||||
public actual final override val isClosed: Boolean
|
public actual final override val isClosed: Boolean
|
||||||
get() = this._state.get() === State.CLOSED
|
get() = this._state.value === State.CLOSED
|
||||||
|
|
||||||
@ManualStateManipulation
|
@ManualStateManipulation
|
||||||
public actual final override fun startUsage() {
|
public actual final override fun startUsage() {
|
||||||
@ -64,9 +63,9 @@ public actual open class ErrorOnConcurrentAccessState : CloseableState.Externall
|
|||||||
|
|
||||||
@Suppress("RedundantModalityModifier")
|
@Suppress("RedundantModalityModifier")
|
||||||
public actual open override fun toString(): String =
|
public actual open override fun toString(): String =
|
||||||
when (this._state.get()) {
|
when (this._state.value) {
|
||||||
State.OPEN -> "<closeable error-on-concurrent-access state [free]>"
|
State.OPEN -> "<closeable error-on-concurrent-access state [free]>"
|
||||||
State.IN_USE -> "<closeable error-on-concurrent-access state [in use]>"
|
State.IN_USE -> "<closeable error-on-concurrent-access state [in use]>"
|
||||||
State.CLOSED -> "<closeable error-on-concurrent-access state [close]>"
|
State.CLOSED -> "<closeable error-on-concurrent-access state [closed]>"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3,19 +3,17 @@
|
|||||||
package ru.landgrafhomyak.utility.closeable_state_1
|
package ru.landgrafhomyak.utility.closeable_state_1
|
||||||
|
|
||||||
import kotlin.contracts.ExperimentalContracts
|
import kotlin.contracts.ExperimentalContracts
|
||||||
import ru.landgrafhomyak.utility.closeable_state_1.internal.AtomicLong
|
import kotlinx.atomicfu.AtomicLong
|
||||||
import ru.landgrafhomyak.utility.closeable_state_1.internal.Misc
|
import kotlinx.atomicfu.atomic
|
||||||
import ru.landgrafhomyak.utility.closeable_state_1.internal.compareAndExchange
|
import kotlinx.atomicfu.update
|
||||||
import ru.landgrafhomyak.utility.closeable_state_1.internal.get
|
import ru.landgrafhomyak.utility.closeable_state_1._MiscNonJvm.compareAndExchange
|
||||||
import ru.landgrafhomyak.utility.closeable_state_1.internal.newAtomicLong
|
|
||||||
import ru.landgrafhomyak.utility.closeable_state_1.internal.update
|
|
||||||
|
|
||||||
public actual open class UsagesCounter : CloseableState.AllowsConcurrency {
|
public actual open class UsagesCounter : CloseableState.AllowsConcurrency {
|
||||||
private val _value: AtomicLong = newAtomicLong(0L)
|
private val _value: AtomicLong = atomic(0L)
|
||||||
|
|
||||||
public actual constructor()
|
public actual constructor()
|
||||||
|
|
||||||
public fun getCurrentUsagesCount(): Long = this._value.get()
|
public fun getCurrentUsagesCount(): Long = this._value.value
|
||||||
|
|
||||||
protected actual open fun throwClosed(): Nothing {
|
protected actual open fun throwClosed(): Nothing {
|
||||||
throw IllegalStateException("Object is closed")
|
throw IllegalStateException("Object is closed")
|
||||||
@ -26,10 +24,10 @@ public actual open class UsagesCounter : CloseableState.AllowsConcurrency {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public actual final override val isClosed: Boolean get() = this._value.get() < 0
|
public actual final override val isClosed: Boolean get() = this._value.value < 0
|
||||||
|
|
||||||
public actual final override fun assertNotClosed() {
|
public actual final override fun assertNotClosed() {
|
||||||
if (this._value.get() < 0) this.throwClosed()
|
if (this._value.value < 0) this.throwClosed()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ManualStateManipulation
|
@ManualStateManipulation
|
||||||
@ -47,7 +45,7 @@ public actual open class UsagesCounter : CloseableState.AllowsConcurrency {
|
|||||||
|
|
||||||
@ManualStateManipulation
|
@ManualStateManipulation
|
||||||
public actual final override fun close() {
|
public actual final override fun close() {
|
||||||
val state = this._value.compareAndExchange(0, Misc.CLOSED_STATE_VALUE)
|
val state = this._value.compareAndExchange(0, _MiscMultiplatform.CLOSED_STATE_VALUE)
|
||||||
when {
|
when {
|
||||||
state > 0 -> this.throwInUse()
|
state > 0 -> this.throwInUse()
|
||||||
state < 0 -> this.throwClosed()
|
state < 0 -> this.throwClosed()
|
||||||
@ -56,7 +54,7 @@ public actual open class UsagesCounter : CloseableState.AllowsConcurrency {
|
|||||||
|
|
||||||
@Suppress("RedundantModalityModifier")
|
@Suppress("RedundantModalityModifier")
|
||||||
public actual open override fun toString(): String {
|
public actual open override fun toString(): String {
|
||||||
val cached = this._value.get()
|
val cached = this._value.value
|
||||||
@Suppress("LiftReturnOrAssignment")
|
@Suppress("LiftReturnOrAssignment")
|
||||||
if (cached < 0)
|
if (cached < 0)
|
||||||
return "<closeable usages counter [closed]>"
|
return "<closeable usages counter [closed]>"
|
||||||
|
|||||||
@ -0,0 +1,24 @@
|
|||||||
|
package ru.landgrafhomyak.utility.closeable_state_1
|
||||||
|
|
||||||
|
import kotlin.jvm.JvmStatic
|
||||||
|
import kotlinx.atomicfu.AtomicLong
|
||||||
|
import kotlinx.atomicfu.AtomicRef
|
||||||
|
import kotlinx.atomicfu.getAndUpdate
|
||||||
|
|
||||||
|
internal object _MiscNonJvm {
|
||||||
|
@JvmStatic
|
||||||
|
internal fun AtomicLong.compareAndExchange(expected: Long, newValue: Long): Long {
|
||||||
|
return this.getAndUpdate { old ->
|
||||||
|
if (old != expected) return@compareAndExchange old
|
||||||
|
return@getAndUpdate newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
internal fun <T> AtomicRef<T>.compareAndExchange(expected: T, newValue: T): T {
|
||||||
|
return this.getAndUpdate { old ->
|
||||||
|
if (old != expected) return@compareAndExchange old
|
||||||
|
return@getAndUpdate newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,77 +0,0 @@
|
|||||||
@file:Suppress("USELESS_CAST", "NOTHING_TO_INLINE")
|
|
||||||
@file:JvmName("AtomicsKt")
|
|
||||||
|
|
||||||
package ru.landgrafhomyak.utility.closeable_state_1.internal
|
|
||||||
|
|
||||||
import kotlin.jvm.JvmName
|
|
||||||
import kotlinx.atomicfu.atomic
|
|
||||||
import kotlinx.atomicfu.AtomicLong as kAtomicLong
|
|
||||||
import kotlinx.atomicfu.AtomicRef as kAtomicRef
|
|
||||||
import kotlinx.atomicfu.update
|
|
||||||
import kotlinx.atomicfu.getAndUpdate
|
|
||||||
|
|
||||||
|
|
||||||
internal actual typealias AtomicLong = kAtomicLong
|
|
||||||
internal actual typealias AtomicReference<T> = kAtomicRef<T>
|
|
||||||
|
|
||||||
|
|
||||||
internal actual inline fun newAtomicLong(initial: Long): AtomicLong =
|
|
||||||
atomic(initial)
|
|
||||||
|
|
||||||
internal actual inline fun <T> newAtomicRef(initial: T): AtomicReference<T> =
|
|
||||||
atomic(initial)
|
|
||||||
|
|
||||||
|
|
||||||
internal actual inline fun AtomicLong.get(): Long =
|
|
||||||
(this as kAtomicLong).value
|
|
||||||
|
|
||||||
internal actual inline fun <T> AtomicReference<T>.get(): T =
|
|
||||||
(this as kAtomicRef).value
|
|
||||||
|
|
||||||
|
|
||||||
internal actual inline fun AtomicLong.update(operator: (Long) -> Long) =
|
|
||||||
(this as kAtomicLong).update(operator)
|
|
||||||
|
|
||||||
internal actual inline fun <T> AtomicReference<T>.update(operator: (T) -> T) =
|
|
||||||
(this as kAtomicRef).update(operator)
|
|
||||||
|
|
||||||
internal actual inline fun AtomicLong.getAndUpdate(operator: (Long) -> Long): Long =
|
|
||||||
(this as kAtomicLong).getAndUpdate(operator)
|
|
||||||
|
|
||||||
internal actual inline fun <T> AtomicReference<T>.getAndUpdate(operator: (T) -> T): T =
|
|
||||||
(this as kAtomicRef).getAndUpdate(operator)
|
|
||||||
|
|
||||||
|
|
||||||
internal actual inline fun AtomicLong.compareAndSet(expected: Long, newValue: Long): Boolean =
|
|
||||||
(this as kAtomicLong).compareAndSet(expected, newValue)
|
|
||||||
|
|
||||||
internal actual inline fun <T> AtomicReference<T>.compareAndSet(expected: T, newValue: T): Boolean =
|
|
||||||
(this as kAtomicRef).compareAndSet(expected, newValue)
|
|
||||||
|
|
||||||
|
|
||||||
private fun AtomicLong.compareAndExchange_impl(expected: Long, newValue: Long): Long {
|
|
||||||
val a = (this as kAtomicLong)
|
|
||||||
return Misc._compareAndExchange(
|
|
||||||
get = a::get,
|
|
||||||
cas = a::compareAndSet,
|
|
||||||
expected = expected, newValue = newValue
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun <T> AtomicReference<T>.compareAndExchange_impl(expected: T, newValue: T): T {
|
|
||||||
val a = (this as kAtomicRef)
|
|
||||||
return Misc._compareAndExchange(
|
|
||||||
get = a::get,
|
|
||||||
cas = a::compareAndSet,
|
|
||||||
expected = expected, newValue = newValue
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal actual inline fun AtomicLong.compareAndExchange(expected: Long, newValue: Long): Long {
|
|
||||||
return this.compareAndExchange_impl(expected, newValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal actual inline fun <T> AtomicReference<T>.compareAndExchange(expected: T, newValue: T): T {
|
|
||||||
return this.compareAndExchange_impl(expected, newValue)
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user