Mutex implementation for linux
This commit is contained in:
commit
5d17c5f7cf
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/.idea/
|
||||||
|
gradle/
|
||||||
|
.gradle/
|
||||||
|
build/
|
||||||
|
*.class
|
||||||
|
*.jar
|
||||||
|
/out/
|
||||||
|
/gradlew*
|
||||||
|
.kotlin/
|
21
build.gradle.kts
Normal file
21
build.gradle.kts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
plugins {
|
||||||
|
kotlin("multiplatform") version "2.1.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
jvm()
|
||||||
|
mingwX64()
|
||||||
|
sourceSets {
|
||||||
|
commonMain {
|
||||||
|
dependencies {
|
||||||
|
implementation("io.ktor:ktor-client-core:3.1.1")
|
||||||
|
implementation("io.ktor:ktor-network:3.1.1")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
modules/low-level/c-interop-utilities/build.gradle.kts
Normal file
21
modules/low-level/c-interop-utilities/build.gradle.kts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
plugins {
|
||||||
|
kotlin("multiplatform") version "2.1.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
mingwX64()
|
||||||
|
linuxX64()
|
||||||
|
macosX64()
|
||||||
|
macosArm64()
|
||||||
|
sourceSets {
|
||||||
|
commonMain {
|
||||||
|
dependencies {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package ru.landgrafhomyak.bgtu.networks0.low_level.c_interop_utilities
|
||||||
|
|
||||||
|
|
||||||
|
import kotlinx.cinterop.CPointer
|
||||||
|
import kotlinx.cinterop.CVariable
|
||||||
|
import kotlinx.cinterop.ExperimentalForeignApi
|
||||||
|
import platform.posix.malloc
|
||||||
|
import kotlinx.cinterop.sizeOf as sizeOf_signed
|
||||||
|
|
||||||
|
@OptIn(ExperimentalForeignApi::class)
|
||||||
|
object CUtilities {
|
||||||
|
inline fun <reified T : CVariable> sizeOf(): ULong = sizeOf_signed<T>().toULong()
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
inline fun <reified T : CVariable> newOrOom() = (malloc(sizeOf<T>()) ?: throw OutOfMemoryError()) as CPointer<T>
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package ru.landgrafhomyak.bgtu.networks0.low_level.c_interop_utilities
|
||||||
|
|
||||||
|
import kotlin.contracts.ExperimentalContracts
|
||||||
|
import kotlin.contracts.InvocationKind
|
||||||
|
import kotlin.contracts.contract
|
||||||
|
import kotlinx.cinterop.ExperimentalForeignApi
|
||||||
|
import kotlinx.cinterop.toKStringFromUtf8
|
||||||
|
import platform.posix.errno
|
||||||
|
import platform.posix.strerror
|
||||||
|
|
||||||
|
|
||||||
|
object LinuxUtilities {
|
||||||
|
@OptIn(ExperimentalForeignApi::class, ExperimentalContracts::class)
|
||||||
|
inline fun throwErrno(
|
||||||
|
createError: (errnoDescription: String) -> Throwable,
|
||||||
|
): Nothing {
|
||||||
|
contract {
|
||||||
|
callsInPlace(createError, InvocationKind.AT_MOST_ONCE)
|
||||||
|
}
|
||||||
|
val origErrno = errno
|
||||||
|
throwErrno(origErrno, createError)
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalForeignApi::class, ExperimentalContracts::class)
|
||||||
|
inline fun throwErrno(
|
||||||
|
origErrno: Int,
|
||||||
|
createError: (errnoDescription: String) -> Throwable,
|
||||||
|
): Nothing {
|
||||||
|
contract {
|
||||||
|
callsInPlace(createError, InvocationKind.AT_MOST_ONCE)
|
||||||
|
}
|
||||||
|
val raw = strerror(origErrno)
|
||||||
|
if (raw != null) {
|
||||||
|
throw createError(raw.toKStringFromUtf8())
|
||||||
|
} else {
|
||||||
|
val strerrErrno = errno
|
||||||
|
try {
|
||||||
|
throw createError("Unknown error (errno=${origErrno})")
|
||||||
|
} catch (t: Throwable) {
|
||||||
|
t.addSuppressed(RuntimeException("Failed to get errno description (failed with errno=${strerrErrno})"))
|
||||||
|
throw t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
modules/low-level/multithreading/build.gradle.kts
Normal file
22
modules/low-level/multithreading/build.gradle.kts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
plugins {
|
||||||
|
kotlin("multiplatform") version "2.1.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
mingwX64()
|
||||||
|
linuxX64()
|
||||||
|
macosX64()
|
||||||
|
macosArm64()
|
||||||
|
sourceSets {
|
||||||
|
nativeMain {
|
||||||
|
dependencies {
|
||||||
|
implementation(project(":modules:low-level:c-interop-utilities"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package ru.landgrafhomyak.bgtu.networks0.low_level.multithreading
|
||||||
|
|
||||||
|
expect class TMutex : AutoCloseable {
|
||||||
|
constructor()
|
||||||
|
|
||||||
|
fun lock()
|
||||||
|
fun unlock()
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
package ru.landgrafhomyak.bgtu.networks0.low_level.multithreading
|
||||||
|
|
||||||
|
import kotlinx.cinterop.CPointer
|
||||||
|
import kotlinx.cinterop.ExperimentalForeignApi
|
||||||
|
import platform.posix.free
|
||||||
|
import platform.posix.pthread_mutex_destroy
|
||||||
|
import platform.posix.pthread_mutex_init
|
||||||
|
import platform.posix.pthread_mutex_lock
|
||||||
|
import platform.posix.pthread_mutex_t
|
||||||
|
import platform.posix.pthread_mutex_unlock
|
||||||
|
import ru.landgrafhomyak.bgtu.networks0.low_level.c_interop_utilities.CUtilities
|
||||||
|
import ru.landgrafhomyak.bgtu.networks0.low_level.c_interop_utilities.LinuxUtilities
|
||||||
|
|
||||||
|
@Suppress("JoinDeclarationAndAssignment", "CanBeVal", "ConvertSecondaryConstructorToPrimary")
|
||||||
|
@OptIn(ExperimentalForeignApi::class)
|
||||||
|
actual class TMutex : AutoCloseable {
|
||||||
|
private var isClosed: Boolean
|
||||||
|
private val descriptor: CPointer<pthread_mutex_t>
|
||||||
|
|
||||||
|
actual constructor() {
|
||||||
|
this.descriptor = CUtilities.newOrOom<pthread_mutex_t>()
|
||||||
|
var err = pthread_mutex_init(this.descriptor, null)
|
||||||
|
if (err != 0)
|
||||||
|
LinuxUtilities.throwErrno(err) { d -> RuntimeException("Failed to create pthreads mutex: $d") }
|
||||||
|
this.isClosed = false
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun lock() {
|
||||||
|
if (this.isClosed) throw IllegalStateException("Mutex was destroyed")
|
||||||
|
var err = pthread_mutex_lock(this.descriptor)
|
||||||
|
if (err != 0)
|
||||||
|
LinuxUtilities.throwErrno(err) { d -> RuntimeException("Failed to lock pthreads mutex: $d") }
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun unlock() {
|
||||||
|
if (this.isClosed) throw IllegalStateException("Mutex was destroyed")
|
||||||
|
var err = pthread_mutex_unlock(this.descriptor)
|
||||||
|
if (err != 0)
|
||||||
|
LinuxUtilities.throwErrno(err) { d -> RuntimeException("Failed to unlock pthreads mutex: $d") }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun close() {
|
||||||
|
if (this.isClosed) return
|
||||||
|
this.isClosed = true
|
||||||
|
var err = pthread_mutex_destroy(this.descriptor)
|
||||||
|
if (err != 0)
|
||||||
|
LinuxUtilities.throwErrno(err) { d -> RuntimeException("Failed to destroy pthreads mutex: $d") }
|
||||||
|
free(this.descriptor)
|
||||||
|
}
|
||||||
|
}
|
3
settings.gradle.kts
Normal file
3
settings.gradle.kts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
include(":modules:low-level:c-interop-utilities")
|
||||||
|
include(":modules:low-level:multithreading")
|
||||||
|
include(":modules:low-level:sockets")
|
Loading…
Reference in New Issue
Block a user