Missed expect functions for atomics and tests
This commit is contained in:
parent
860ffa98e0
commit
e8d899928e
@ -63,10 +63,16 @@ xomrk {
|
|||||||
|
|
||||||
val commonMain by getting {
|
val commonMain by getting {
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly(kotlinStdlibDependency)
|
implementation(kotlinStdlibDependency)
|
||||||
implementation("ru.landgrafhomyak.utility:highlevel-try-finally:0.5")
|
implementation("ru.landgrafhomyak.utility:highlevel-try-finally:0.5")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val commonTest by getting {
|
||||||
|
dependencies {
|
||||||
|
implementation("org.jetbrains.kotlin:kotlin-test:${this@kotlin.coreLibrariesVersion}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val jvmMain by getting {
|
val jvmMain by getting {
|
||||||
dependsOn(commonMain)
|
dependsOn(commonMain)
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose2
|
|||||||
|
|
||||||
@OptIn(ManualStateManipulation::class)
|
@OptIn(ManualStateManipulation::class)
|
||||||
@JvmName("use\$kt")
|
@JvmName("use\$kt")
|
||||||
public inline fun <R> CloseableState.use(block: () -> R): R {
|
public inline fun <R> CloseableState.withUse(block: () -> R): R {
|
||||||
contract {
|
contract {
|
||||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,10 @@
|
|||||||
|
package ru.landgrafhomyak.utility.closeable_state
|
||||||
|
|
||||||
|
import kotlin.test.Test
|
||||||
|
|
||||||
|
internal class ErrorOnConcurrentAccessStateTest: _CloseableStateExternallySynchronizedAbstractTestSet() {
|
||||||
|
override fun createState(): CloseableState = ErrorOnConcurrentAccessState()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun test() {}
|
||||||
|
}
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
package ru.landgrafhomyak.utility.closeable_state
|
||||||
|
|
||||||
|
internal class TestThrowable: Throwable("If this throwable isn't caught then test is bad written") {
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
package ru.landgrafhomyak.utility.closeable_state
|
||||||
|
|
||||||
|
import kotlin.test.Test
|
||||||
|
|
||||||
|
internal class UsagesCounterTest: _CloseableStateAllowsConcurrencyAbstractTestSet() {
|
||||||
|
override fun createState(): CloseableState = UsagesCounter()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun test() {}
|
||||||
|
}
|
||||||
@ -0,0 +1,91 @@
|
|||||||
|
package ru.landgrafhomyak.utility.closeable_state
|
||||||
|
|
||||||
|
import kotlin.test.Test
|
||||||
|
|
||||||
|
@OptIn(ManualStateManipulation::class)
|
||||||
|
internal abstract class _CloseableStateAbstractTestSet {
|
||||||
|
abstract fun createState(): CloseableState
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testInstantClose() {
|
||||||
|
this.createState().close()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testOneManual() {
|
||||||
|
val s = this.createState()
|
||||||
|
s.startUsage()
|
||||||
|
s.finishUsage()
|
||||||
|
s.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testOneAuto() {
|
||||||
|
val s = this.createState()
|
||||||
|
s.withUse { }
|
||||||
|
s.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testSubsequentManual() {
|
||||||
|
val s = this.createState()
|
||||||
|
s.startUsage()
|
||||||
|
s.finishUsage()
|
||||||
|
s.startUsage()
|
||||||
|
s.finishUsage()
|
||||||
|
s.startUsage()
|
||||||
|
s.finishUsage()
|
||||||
|
s.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testSubsequentAuto() {
|
||||||
|
val s = this.createState()
|
||||||
|
s.withUse { }
|
||||||
|
s.withUse { }
|
||||||
|
s.withUse { }
|
||||||
|
s.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testTryStartSuccess() {
|
||||||
|
val s = this.createState()
|
||||||
|
s.tryStartUsage { }
|
||||||
|
s.finishUsage()
|
||||||
|
s.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testTryStartFailed() {
|
||||||
|
val s = this.createState()
|
||||||
|
try {
|
||||||
|
s.tryStartUsage { throw TestThrowable() }
|
||||||
|
} catch (_: TestThrowable) {
|
||||||
|
}
|
||||||
|
s.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testTryFinishSuccess() {
|
||||||
|
val s = this.createState()
|
||||||
|
s.startUsage()
|
||||||
|
s.tryFinishUsage { }
|
||||||
|
s.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testTryFinishFailed() {
|
||||||
|
val s = this.createState()
|
||||||
|
s.startUsage()
|
||||||
|
try {
|
||||||
|
s.tryFinishUsage { throw TestThrowable() }
|
||||||
|
} catch (_: TestThrowable) {
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
s.close()
|
||||||
|
} catch (_: Throwable) {}
|
||||||
|
s.finishUsage()
|
||||||
|
s.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package ru.landgrafhomyak.utility.closeable_state
|
||||||
|
|
||||||
|
import kotlin.test.Test
|
||||||
|
|
||||||
|
@OptIn(ManualStateManipulation::class)
|
||||||
|
internal abstract class _CloseableStateAllowsConcurrencyAbstractTestSet: _CloseableStateAbstractTestSet() {
|
||||||
|
abstract override fun createState(): CloseableState
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testRecursionManual() {
|
||||||
|
val s = this.createState()
|
||||||
|
s.startUsage()
|
||||||
|
s.startUsage()
|
||||||
|
s.finishUsage()
|
||||||
|
s.finishUsage()
|
||||||
|
s.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testRecursionAuto() {
|
||||||
|
val s = this.createState()
|
||||||
|
s.withUse { s.withUse { } }
|
||||||
|
s.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package ru.landgrafhomyak.utility.closeable_state
|
||||||
|
|
||||||
|
import kotlin.test.Test
|
||||||
|
|
||||||
|
@OptIn(ManualStateManipulation::class)
|
||||||
|
internal abstract class _CloseableStateExternallySynchronizedAbstractTestSet : _CloseableStateAbstractTestSet() {
|
||||||
|
abstract override fun createState(): CloseableState
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testRecursionManual() {
|
||||||
|
val s = this.createState()
|
||||||
|
s.startUsage()
|
||||||
|
try {
|
||||||
|
s.startUsage()
|
||||||
|
} catch (_: Throwable) {
|
||||||
|
}
|
||||||
|
s.finishUsage()
|
||||||
|
s.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testRecursionAuto() {
|
||||||
|
val s = this.createState()
|
||||||
|
s.withUse {
|
||||||
|
try {
|
||||||
|
s.withUse {}
|
||||||
|
} catch (_: Throwable) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,9 +4,9 @@ import org.testng.annotations.Test
|
|||||||
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose1
|
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose1
|
||||||
import ru.landgrafhomyak.utility.closeable_state.ManualStateManipulation
|
import ru.landgrafhomyak.utility.closeable_state.ManualStateManipulation
|
||||||
import ru.landgrafhomyak.utility.closeable_state.UsagesCounter
|
import ru.landgrafhomyak.utility.closeable_state.UsagesCounter
|
||||||
import ru.landgrafhomyak.utility.closeable_state.use
|
import ru.landgrafhomyak.utility.closeable_state.withUse
|
||||||
|
|
||||||
@Test
|
@Test(enabled = false)
|
||||||
class KotlinStdlibDependencyTest {
|
class KotlinStdlibDependencyTest {
|
||||||
@Test
|
@Test
|
||||||
fun testNoKotlinStdlib() {
|
fun testNoKotlinStdlib() {
|
||||||
@ -52,11 +52,11 @@ class KotlinStdlibDependencyTest {
|
|||||||
fun testWithRef() {
|
fun testWithRef() {
|
||||||
try {
|
try {
|
||||||
val refcnt = UsagesCounter()
|
val refcnt = UsagesCounter()
|
||||||
refcnt.use {
|
refcnt.withUse {
|
||||||
return@use CustomUnit
|
return@withUse CustomUnit
|
||||||
}
|
}
|
||||||
refcnt.use w1@{
|
refcnt.withUse w1@{
|
||||||
return@w1 refcnt.use w2@{
|
return@w1 refcnt.withUse w2@{
|
||||||
return@w2 CustomUnit
|
return@w2 CustomUnit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,7 +70,7 @@ class KotlinStdlibDependencyTest {
|
|||||||
fun testWithRef_Err() {
|
fun testWithRef_Err() {
|
||||||
try {
|
try {
|
||||||
val refcnt = UsagesCounter()
|
val refcnt = UsagesCounter()
|
||||||
refcnt.use {
|
refcnt.withUse {
|
||||||
throw CustomTestException()
|
throw CustomTestException()
|
||||||
}
|
}
|
||||||
} catch (_: CustomTestException) {
|
} catch (_: CustomTestException) {
|
||||||
|
|||||||
@ -1,8 +1,77 @@
|
|||||||
|
@file:Suppress("USELESS_CAST", "NOTHING_TO_INLINE")
|
||||||
@file:JvmName("AtomicsKt")
|
@file:JvmName("AtomicsKt")
|
||||||
|
|
||||||
package ru.landgrafhomyak.utility.closeable_state.internal
|
package ru.landgrafhomyak.utility.closeable_state.internal
|
||||||
|
|
||||||
import kotlin.jvm.JvmName
|
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 = kotlinx.atomicfu.AtomicLong
|
internal actual typealias AtomicLong = kAtomicLong
|
||||||
internal actual typealias AtomicReference<T> = kotlinx.atomicfu.AtomicRef<T>
|
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