Applied tryFinallyChain and test program was rewritten with .use{}

This commit is contained in:
Andrew Golovashevich 2025-03-22 15:57:21 +03:00
parent 9538888b77
commit 5cfb5551c4
9 changed files with 40 additions and 41 deletions

@ -1 +1 @@
Subproject commit ef1d72ca10c361d2eead443d99241a088e130174
Subproject commit 88c8da21e4ec11c9755b6770565685bdc29acbca

View File

@ -3,6 +3,7 @@ package ru.landgrafhomyak.bgtu.networks0.low_level.multithreading
import ru.landgrafhomyak.bgtu.networks0.utilities.CloseableRefCounter
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose1
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose2
import ru.landgrafhomyak.utility.highlevel_try_finally.tryFinallyChain
class CountDownLatch : AutoCloseable {
private val _refcnt: CloseableRefCounter
@ -37,9 +38,9 @@ class CountDownLatch : AutoCloseable {
override fun close() {
this._refcnt.close("Latch is still in use")
safeAutoClose1(
action = this._condition::close,
finally = this._mutex::close
)
tryFinallyChain { chain ->
chain.action { this._condition.close() }
chain.action { this._mutex.close() }
}
}
}

View File

@ -16,6 +16,7 @@ import ru.landgrafhomyak.bgtu.networks0.low_level.c_interop_utilities.PosixUtili
import ru.landgrafhomyak.bgtu.networks0.utilities.CloseableRefCounter
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose1
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose2
import ru.landgrafhomyak.utility.highlevel_try_finally.tryFinallyChain
@OptIn(ExperimentalForeignApi::class)
@ -56,13 +57,13 @@ actual class Condition : AutoCloseable {
override fun close() {
this._refcnt.close("There are waiting threads on this pthreads condition")
safeAutoClose1(
action = {
tryFinallyChain { chain ->
chain.action {
var err = pthread_cond_destroy(this._descriptor)
if (err != 0)
PosixUtilities.throwErrno(err) { d -> RuntimeException("Failed to destroy pthreads condition: $d") }
},
finally = { nativeHeap.free(this._descriptor) }
)
}
chain.action { nativeHeap.free(this._descriptor) }
}
}
}

View File

@ -15,6 +15,7 @@ import ru.landgrafhomyak.bgtu.networks0.low_level.c_interop_utilities.PosixUtili
import ru.landgrafhomyak.bgtu.networks0.utilities.CloseableRefCounter
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose1
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose2
import ru.landgrafhomyak.utility.highlevel_try_finally.tryFinallyChain
@OptIn(ExperimentalForeignApi::class, Mutex.RefcntAccess::class)
actual class Mutex : AutoCloseable {
@ -53,13 +54,13 @@ actual class Mutex : AutoCloseable {
override fun close() {
this._refcnt.close("There are waiting threads on this pthreads mutex")
safeAutoClose1(
action = {
tryFinallyChain { chain ->
chain.action {
var err = pthread_mutex_destroy(this._descriptor)
if (err != 0)
PosixUtilities.throwErrno(err) { d -> RuntimeException("Failed to destroy pthreads mutex: $d") }
},
finally = { nativeHeap.free(this._descriptor) }
)
}
chain.action { nativeHeap.free(this._descriptor) }
}
}
}

View File

@ -63,6 +63,7 @@ actual class Thread : AutoCloseable {
safeAutoClose2(onError = { this._state.value = State.PENDING }) {
this._bootstrapArgRef.get().startSignal.decrement()
}
this._state.value = State.RUNNING
}
actual fun join(): Throwable? {

View File

@ -32,6 +32,7 @@ import ru.landgrafhomyak.bgtu.networks0.low_level.multithreading.withLock
import ru.landgrafhomyak.bgtu.networks0.utilities.CloseableRefCounter
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose1
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose2
import ru.landgrafhomyak.utility.highlevel_try_finally.tryFinallyChain
import ru.landgrafhomyak.bgtu.networks0.low_level.multithreading.Mutex as TMutex
@OptIn(ExperimentalForeignApi::class)
@ -226,20 +227,12 @@ class EpollSocketEventLoop : SocketEventLoopScope.Closeable {
this@EpollSocketEventLoop._waitForRead(this.__metadata)
override fun _free() {
safeAutoClose1(
action = { this@EpollSocketEventLoop._remove(this.__metadata) },
finally = {
safeAutoClose1(
action = this@EpollSocketEventLoop._socketsCount::decref,
finally = {
safeAutoClose1(
action = this.__metadata::close,
finally = { super.close() }
)
}
)
}
)
tryFinallyChain { chain ->
chain.action { this@EpollSocketEventLoop._remove(this.__metadata) }
chain.action { this@EpollSocketEventLoop._socketsCount.decref() }
chain.action { this.__metadata.close() }
chain.action { super._free() }
}
}
}
}

View File

@ -14,7 +14,7 @@ fun AtomicLong.compareAndExchange(expected: Long, newValue: Long): Long {
fun <T> AtomicRef<T>.compareAndExchange(expected: T, newValue: T): T {
while (true) {
val old = this.value
if (old === expected) return old
if (old !== expected) return old
if (this.compareAndSet(old, newValue)) return old
}
}

View File

@ -19,17 +19,18 @@ class EventLoopRoutine(private val loop: EpollSocketEventLoop) : Thread.Routine
fun main() {
try {
val loop = EpollSocketEventLoop()
EpollSocketEventLoop().use { loop ->
Thread(EventLoopRoutine(loop)).use { loopThread ->
loopThread.start()
loop.pinger_IPv4("8.8.8.8").use { googleSock ->
val loopThread = Thread(EventLoopRoutine(loop))
loopThread.start()
val googleSock = loop.pinger_IPv4("8.8.8.8")
runBlocking {
while (true) {
print("google: ${googleSock.ping(1000u)}ms\n")
delay(1000)
runBlocking {
for (i in 0..10) {
print("google: ${googleSock.ping(1000u)}ms\n")
delay(1000)
}
}
}
}
}
} catch (e: Throwable) {

View File

@ -30,4 +30,5 @@ include(":modules:low-level:c-interop-utilities")
include(":modules:low-level:multithreading")
include(":modules:low-level:sockets")
include(":modules:icmp")
include(":programs:test")
include(":programs:test")
include(":programs:test2")