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