Minor fixes and runnable test program
This commit is contained in:
parent
2b5eed2abe
commit
18886705af
@ -21,6 +21,6 @@ fun KotlinMultiplatformExtension.suppressWarnings(vararg warningNames: String) {
|
||||
|
||||
fun KotlinMultiplatformExtension.configureWarnings() {
|
||||
this.configureAllCompilersOptions a@{ this@a.freeCompilerArgs.addAll("-Wextra", "-Xexpect-actual-classes") }
|
||||
this.suppressWarnings("JoinDeclarationAndAssignment", "CanBeVal", "ConvertSecondaryConstructorToPrimary", "FunctionName", "PropertyName", "PrivatePropertyName")
|
||||
this.suppressWarnings()
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ internal class _Refcnt(private val _errMessage: String) {
|
||||
this.checkNotClosed()
|
||||
return _safeAutoClose2(onSuccess = this::decref, action = block)
|
||||
}
|
||||
|
||||
fun close(errExistRefs: String) {
|
||||
val state = this._value.compareAndExchange(0, -1)
|
||||
when {
|
||||
@ -47,4 +48,12 @@ internal class _Refcnt(private val _errMessage: String) {
|
||||
this.incref()
|
||||
return _safeAutoClose1(finally = this::decref, action = protected)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
val refcntCached = this._value.value
|
||||
if (refcntCached < 0)
|
||||
return "<ref counter [closed]>"
|
||||
else
|
||||
return "<ref counter [${refcntCached}]>"
|
||||
}
|
||||
}
|
@ -9,5 +9,6 @@ inline fun <R> Mutex.withLock(synchronizedBlock: () -> R): R {
|
||||
contract {
|
||||
callsInPlace(synchronizedBlock, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
this.lock()
|
||||
return _safeAutoClose1(finally = this::unlock, synchronizedBlock)
|
||||
}
|
@ -24,12 +24,12 @@ internal fun <T> AtomicRef<T>.compareAndExchange(expected: T, newValue: T): T {
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("WRONG_INVOCATION_KIND")
|
||||
@PublishedApi
|
||||
internal inline fun <R> _safeAutoClose1(
|
||||
finally: () -> Unit,
|
||||
action: () -> R
|
||||
): R {
|
||||
@Suppress("WRONG_INVOCATION_KIND")
|
||||
contract {
|
||||
callsInPlace(action, InvocationKind.EXACTLY_ONCE)
|
||||
callsInPlace(finally, InvocationKind.EXACTLY_ONCE)
|
||||
@ -37,13 +37,13 @@ internal inline fun <R> _safeAutoClose1(
|
||||
return _safeAutoClose3(onAbort = finally, onSuccess = finally, onCrossReturn = finally, action = action)
|
||||
}
|
||||
|
||||
@Suppress("WRONG_INVOCATION_KIND")
|
||||
@PublishedApi
|
||||
internal inline fun <R> _safeAutoClose2(
|
||||
onAbort: () -> Unit = {},
|
||||
onSuccess: () -> Unit = {},
|
||||
action: () -> R
|
||||
): R {
|
||||
@Suppress("WRONG_INVOCATION_KIND")
|
||||
contract {
|
||||
callsInPlace(action, InvocationKind.EXACTLY_ONCE)
|
||||
callsInPlace(onAbort, InvocationKind.AT_MOST_ONCE)
|
||||
@ -52,13 +52,13 @@ internal inline fun <R> _safeAutoClose2(
|
||||
return _safeAutoClose3(onAbort = onAbort, onSuccess = onSuccess, onCrossReturn = onSuccess, action = action)
|
||||
}
|
||||
|
||||
@Suppress("WRONG_INVOCATION_KIND")
|
||||
@PublishedApi
|
||||
internal inline fun <R> _safeAutoClose2e(
|
||||
onAbort: (Throwable) -> Unit = {},
|
||||
onAbort: (Throwable) -> Unit = { _ -> },
|
||||
onSuccess: () -> Unit = {},
|
||||
action: () -> R
|
||||
): R {
|
||||
@Suppress("WRONG_INVOCATION_KIND")
|
||||
contract {
|
||||
callsInPlace(action, InvocationKind.EXACTLY_ONCE)
|
||||
callsInPlace(onAbort, InvocationKind.AT_MOST_ONCE)
|
||||
@ -85,7 +85,7 @@ internal inline fun <R> _safeAutoClose3(
|
||||
|
||||
@PublishedApi
|
||||
internal inline fun <R> _safeAutoClose3e(
|
||||
onAbort: (Throwable) -> Unit = {},
|
||||
onAbort: (Throwable) -> Unit = { _ -> },
|
||||
onSuccess: () -> Unit = {},
|
||||
onCrossReturn: () -> Unit = {},
|
||||
action: () -> R
|
||||
|
@ -39,11 +39,11 @@ actual class Thread : AutoCloseable {
|
||||
_safeAutoClose2(onAbort = this._threadBindings::free) {
|
||||
var err = this._threadBindings.create(
|
||||
null,
|
||||
staticCFunction(Thread::_threadBootstrap),
|
||||
staticCFunction({ arg -> return@staticCFunction Thread._threadBootstrap(arg) }),
|
||||
this._bootstrapArgRef.asCPointer()
|
||||
)
|
||||
if (err == 0)
|
||||
PosixUtilities.throwErrno(err) { d -> RuntimeException("Failed to create pthreads thread") }
|
||||
if (err != 0)
|
||||
PosixUtilities.throwErrno(err) { d -> RuntimeException("Failed to create pthreads thread: $d") }
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@ actual class Thread : AutoCloseable {
|
||||
State.STARTING, State.RUNNING, State.PENDING -> {}
|
||||
}
|
||||
var err = this._threadBindings.join(null)
|
||||
if (err == 0)
|
||||
if (err != 0)
|
||||
PosixUtilities.throwErrno(err) { d -> RuntimeException("Failed to create pthreads thread") }
|
||||
return this._bootstrapArgRef.get().exitedWithError
|
||||
}
|
||||
@ -86,8 +86,8 @@ actual class Thread : AutoCloseable {
|
||||
_safeAutoClose1(
|
||||
action = {
|
||||
var err = this._threadBindings.join(null)
|
||||
if (err == 0)
|
||||
PosixUtilities.throwErrno(err) { d -> RuntimeException("Failed to create pthreads thread") }
|
||||
if (err != 0)
|
||||
PosixUtilities.throwErrno(err) { d -> RuntimeException("Failed to destroy pthreads thread: $d") }
|
||||
},
|
||||
finally = {
|
||||
_safeAutoClose1(
|
||||
@ -115,6 +115,7 @@ actual class Thread : AutoCloseable {
|
||||
},
|
||||
onSuccess = { context.threadState.value = State.FINISHED },
|
||||
action = {
|
||||
context.startSignal.await()
|
||||
context.routine.run()
|
||||
}
|
||||
)
|
||||
|
25
programs/test/build.gradle.kts
Normal file
25
programs/test/build.gradle.kts
Normal file
@ -0,0 +1,25 @@
|
||||
plugins {
|
||||
kotlin("multiplatform")
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven("https://maven.landgrafhomyak.ru/")
|
||||
}
|
||||
|
||||
|
||||
kotlin {
|
||||
linuxX64 {
|
||||
this.binaries.executable {
|
||||
entryPoint("main")
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
linuxX64Main {
|
||||
dependencies {
|
||||
implementation(project(":modules:low-level:multithreading"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
42
programs/test/src/linuxX64Main/kotlin/main.kt
Normal file
42
programs/test/src/linuxX64Main/kotlin/main.kt
Normal file
@ -0,0 +1,42 @@
|
||||
import platform.posix.sleep
|
||||
import ru.landgrafhomyak.bgtu.networks0.low_level.multithreading.Thread
|
||||
|
||||
class Printer(private val prefix: String) : Thread.Routine {
|
||||
override fun run() {
|
||||
for (i in 0..3) {
|
||||
print("${this.prefix}: ${i}\n")
|
||||
sleep(1u)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun main() {
|
||||
try {
|
||||
println("entry")
|
||||
|
||||
val t1 = Thread(Printer("t1"))
|
||||
val t2 = Thread(Printer("t2"))
|
||||
val t3 = Thread(Printer("t3"))
|
||||
val t4 = Thread(Printer("t4"))
|
||||
|
||||
println("created")
|
||||
sleep(2u)
|
||||
println("starting...")
|
||||
|
||||
t1.start()
|
||||
t2.start()
|
||||
t3.start()
|
||||
t4.start()
|
||||
|
||||
print("started\n")
|
||||
|
||||
t1.join()?.let(Throwable::printStackTrace)
|
||||
t2.join()?.let(Throwable::printStackTrace)
|
||||
t3.join()?.let(Throwable::printStackTrace)
|
||||
t4.join()?.let(Throwable::printStackTrace)
|
||||
|
||||
println("finished")
|
||||
} catch (e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
@ -23,4 +23,5 @@ pluginManagement {
|
||||
}
|
||||
include(":modules:low-level:c-interop-utilities")
|
||||
include(":modules:low-level:multithreading")
|
||||
include(":modules:low-level:sockets")
|
||||
include(":modules:low-level:sockets")
|
||||
include(":programs:test")
|
Loading…
Reference in New Issue
Block a user