Applied tryFinallyChain and test program was rewritten with .use{}
This commit is contained in:
parent
9538888b77
commit
5cfb5551c4
@ -1 +1 @@
|
|||||||
Subproject commit ef1d72ca10c361d2eead443d99241a088e130174
|
Subproject commit 88c8da21e4ec11c9755b6770565685bdc29acbca
|
@ -3,6 +3,7 @@ package ru.landgrafhomyak.bgtu.networks0.low_level.multithreading
|
|||||||
import ru.landgrafhomyak.bgtu.networks0.utilities.CloseableRefCounter
|
import ru.landgrafhomyak.bgtu.networks0.utilities.CloseableRefCounter
|
||||||
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose1
|
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose1
|
||||||
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose2
|
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose2
|
||||||
|
import ru.landgrafhomyak.utility.highlevel_try_finally.tryFinallyChain
|
||||||
|
|
||||||
class CountDownLatch : AutoCloseable {
|
class CountDownLatch : AutoCloseable {
|
||||||
private val _refcnt: CloseableRefCounter
|
private val _refcnt: CloseableRefCounter
|
||||||
@ -37,9 +38,9 @@ class CountDownLatch : AutoCloseable {
|
|||||||
|
|
||||||
override fun close() {
|
override fun close() {
|
||||||
this._refcnt.close("Latch is still in use")
|
this._refcnt.close("Latch is still in use")
|
||||||
safeAutoClose1(
|
tryFinallyChain { chain ->
|
||||||
action = this._condition::close,
|
chain.action { this._condition.close() }
|
||||||
finally = this._mutex::close
|
chain.action { this._mutex.close() }
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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.bgtu.networks0.utilities.CloseableRefCounter
|
||||||
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose1
|
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose1
|
||||||
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose2
|
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose2
|
||||||
|
import ru.landgrafhomyak.utility.highlevel_try_finally.tryFinallyChain
|
||||||
|
|
||||||
|
|
||||||
@OptIn(ExperimentalForeignApi::class)
|
@OptIn(ExperimentalForeignApi::class)
|
||||||
@ -56,13 +57,13 @@ actual class Condition : AutoCloseable {
|
|||||||
|
|
||||||
override fun close() {
|
override fun close() {
|
||||||
this._refcnt.close("There are waiting threads on this pthreads condition")
|
this._refcnt.close("There are waiting threads on this pthreads condition")
|
||||||
safeAutoClose1(
|
tryFinallyChain { chain ->
|
||||||
action = {
|
chain.action {
|
||||||
var err = pthread_cond_destroy(this._descriptor)
|
var err = pthread_cond_destroy(this._descriptor)
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
PosixUtilities.throwErrno(err) { d -> RuntimeException("Failed to destroy pthreads condition: $d") }
|
PosixUtilities.throwErrno(err) { d -> RuntimeException("Failed to destroy pthreads condition: $d") }
|
||||||
},
|
}
|
||||||
finally = { nativeHeap.free(this._descriptor) }
|
chain.action { nativeHeap.free(this._descriptor) }
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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.bgtu.networks0.utilities.CloseableRefCounter
|
||||||
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose1
|
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose1
|
||||||
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose2
|
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose2
|
||||||
|
import ru.landgrafhomyak.utility.highlevel_try_finally.tryFinallyChain
|
||||||
|
|
||||||
@OptIn(ExperimentalForeignApi::class, Mutex.RefcntAccess::class)
|
@OptIn(ExperimentalForeignApi::class, Mutex.RefcntAccess::class)
|
||||||
actual class Mutex : AutoCloseable {
|
actual class Mutex : AutoCloseable {
|
||||||
@ -53,13 +54,13 @@ actual class Mutex : AutoCloseable {
|
|||||||
|
|
||||||
override fun close() {
|
override fun close() {
|
||||||
this._refcnt.close("There are waiting threads on this pthreads mutex")
|
this._refcnt.close("There are waiting threads on this pthreads mutex")
|
||||||
safeAutoClose1(
|
tryFinallyChain { chain ->
|
||||||
action = {
|
chain.action {
|
||||||
var err = pthread_mutex_destroy(this._descriptor)
|
var err = pthread_mutex_destroy(this._descriptor)
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
PosixUtilities.throwErrno(err) { d -> RuntimeException("Failed to destroy pthreads mutex: $d") }
|
PosixUtilities.throwErrno(err) { d -> RuntimeException("Failed to destroy pthreads mutex: $d") }
|
||||||
},
|
}
|
||||||
finally = { nativeHeap.free(this._descriptor) }
|
chain.action { nativeHeap.free(this._descriptor) }
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -63,6 +63,7 @@ actual class Thread : AutoCloseable {
|
|||||||
safeAutoClose2(onError = { this._state.value = State.PENDING }) {
|
safeAutoClose2(onError = { this._state.value = State.PENDING }) {
|
||||||
this._bootstrapArgRef.get().startSignal.decrement()
|
this._bootstrapArgRef.get().startSignal.decrement()
|
||||||
}
|
}
|
||||||
|
this._state.value = State.RUNNING
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun join(): Throwable? {
|
actual fun join(): Throwable? {
|
||||||
|
@ -32,6 +32,7 @@ import ru.landgrafhomyak.bgtu.networks0.low_level.multithreading.withLock
|
|||||||
import ru.landgrafhomyak.bgtu.networks0.utilities.CloseableRefCounter
|
import ru.landgrafhomyak.bgtu.networks0.utilities.CloseableRefCounter
|
||||||
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose1
|
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose1
|
||||||
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose2
|
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
|
import ru.landgrafhomyak.bgtu.networks0.low_level.multithreading.Mutex as TMutex
|
||||||
|
|
||||||
@OptIn(ExperimentalForeignApi::class)
|
@OptIn(ExperimentalForeignApi::class)
|
||||||
@ -226,20 +227,12 @@ class EpollSocketEventLoop : SocketEventLoopScope.Closeable {
|
|||||||
this@EpollSocketEventLoop._waitForRead(this.__metadata)
|
this@EpollSocketEventLoop._waitForRead(this.__metadata)
|
||||||
|
|
||||||
override fun _free() {
|
override fun _free() {
|
||||||
safeAutoClose1(
|
tryFinallyChain { chain ->
|
||||||
action = { this@EpollSocketEventLoop._remove(this.__metadata) },
|
chain.action { this@EpollSocketEventLoop._remove(this.__metadata) }
|
||||||
finally = {
|
chain.action { this@EpollSocketEventLoop._socketsCount.decref() }
|
||||||
safeAutoClose1(
|
chain.action { this.__metadata.close() }
|
||||||
action = this@EpollSocketEventLoop._socketsCount::decref,
|
chain.action { super._free() }
|
||||||
finally = {
|
}
|
||||||
safeAutoClose1(
|
|
||||||
action = this.__metadata::close,
|
|
||||||
finally = { super.close() }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ fun AtomicLong.compareAndExchange(expected: Long, newValue: Long): Long {
|
|||||||
fun <T> AtomicRef<T>.compareAndExchange(expected: T, newValue: T): T {
|
fun <T> AtomicRef<T>.compareAndExchange(expected: T, newValue: T): T {
|
||||||
while (true) {
|
while (true) {
|
||||||
val old = this.value
|
val old = this.value
|
||||||
if (old === expected) return old
|
if (old !== expected) return old
|
||||||
if (this.compareAndSet(old, newValue)) return old
|
if (this.compareAndSet(old, newValue)) return old
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,17 +19,18 @@ class EventLoopRoutine(private val loop: EpollSocketEventLoop) : Thread.Routine
|
|||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
try {
|
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))
|
runBlocking {
|
||||||
loopThread.start()
|
for (i in 0..10) {
|
||||||
|
print("google: ${googleSock.ping(1000u)}ms\n")
|
||||||
val googleSock = loop.pinger_IPv4("8.8.8.8")
|
delay(1000)
|
||||||
|
}
|
||||||
runBlocking {
|
}
|
||||||
while (true) {
|
}
|
||||||
print("google: ${googleSock.ping(1000u)}ms\n")
|
|
||||||
delay(1000)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
|
@ -30,4 +30,5 @@ include(":modules:low-level:c-interop-utilities")
|
|||||||
include(":modules:low-level:multithreading")
|
include(":modules:low-level:multithreading")
|
||||||
include(":modules:low-level:sockets")
|
include(":modules:low-level:sockets")
|
||||||
include(":modules:icmp")
|
include(":modules:icmp")
|
||||||
include(":programs:test")
|
include(":programs:test")
|
||||||
|
include(":programs:test2")
|
Loading…
Reference in New Issue
Block a user