Thread local variable impl on WinApi
This commit is contained in:
parent
f8cb01799d
commit
650213fc4c
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,4 +1,4 @@
|
|||||||
/.idea/
|
.idea/
|
||||||
gradle/
|
gradle/
|
||||||
.gradle/
|
.gradle/
|
||||||
build/
|
build/
|
||||||
|
|||||||
@ -22,6 +22,7 @@ version = "0.1"
|
|||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
maven("https://maven.landgrafhomyak.ru/")
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
@ -68,7 +69,13 @@ kotlin {
|
|||||||
compileOnly("org.jetbrains.kotlin:kotlin-annotations-jvm:${this@kotlin.coreLibrariesVersion}")
|
compileOnly("org.jetbrains.kotlin:kotlin-annotations-jvm:${this@kotlin.coreLibrariesVersion}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mingwX64().compilations["main"].defaultSourceSet {
|
||||||
|
dependencies {
|
||||||
|
implementation("ru.landgrafhomyak.utility:highlevel-try-finally:0.6")
|
||||||
|
implementation("ru.landgrafhomyak.utility:closeable-state-1:1.2")
|
||||||
|
implementation("ru.landgrafhomyak.utility:kotlin-native-interop-utilities-0:0.1")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val notJvmMain by creating { dependsOn(commonMain) }
|
val notJvmMain by creating { dependsOn(commonMain) }
|
||||||
val notJvmTest by creating { dependsOn(commonTest) }
|
val notJvmTest by creating { dependsOn(commonTest) }
|
||||||
@ -96,11 +103,13 @@ kotlin {
|
|||||||
this@target.compilations.getByName("main").defaultSourceSet.dependsOn(multithreadPlatformMain)
|
this@target.compilations.getByName("main").defaultSourceSet.dependsOn(multithreadPlatformMain)
|
||||||
this@target.compilations.getByName("test").defaultSourceSet.dependsOn(multithreadPlatformTest)
|
this@target.compilations.getByName("test").defaultSourceSet.dependsOn(multithreadPlatformTest)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val windowsMain by creating { dependsOn(multithreadPlatformMain) }
|
||||||
|
val windowsTest by creating { dependsOn(multithreadPlatformTest) }
|
||||||
|
mingwX64().compilations["main"].defaultSourceSet.dependsOn(windowsMain)
|
||||||
|
mingwX64().compilations["test"].defaultSourceSet.dependsOn(windowsTest)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
publishing {
|
publishing {
|
||||||
|
|||||||
@ -0,0 +1,67 @@
|
|||||||
|
package ru.landgrafhomyak.multitasking_0.threads
|
||||||
|
|
||||||
|
import kotlin.concurrent.atomics.ExperimentalAtomicApi
|
||||||
|
import kotlinx.cinterop.ExperimentalForeignApi
|
||||||
|
import kotlinx.cinterop.StableRef
|
||||||
|
import platform.windows.DWORD
|
||||||
|
import platform.windows.ERROR_SUCCESS
|
||||||
|
import platform.windows.GetLastError
|
||||||
|
import platform.windows.LPVOID
|
||||||
|
import platform.windows.TLS_OUT_OF_INDEXES
|
||||||
|
import platform.windows.TlsAlloc
|
||||||
|
import platform.windows.TlsFree
|
||||||
|
import platform.windows.TlsGetValue
|
||||||
|
import platform.windows.TlsSetValue
|
||||||
|
import ru.landgrafhomyak.utility.closeable_state_1.CloseableState
|
||||||
|
import ru.landgrafhomyak.utility.closeable_state_1.ManualStateManipulation
|
||||||
|
import ru.landgrafhomyak.utility.closeable_state_1.OwnedUsagesCounter
|
||||||
|
import ru.landgrafhomyak.utility.closeable_state_1.withUse
|
||||||
|
import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose2
|
||||||
|
import ru.landgrafhomyak.utility.kotlin_native_interop_stdlib_0.windows.WindowsApiException
|
||||||
|
import ru.landgrafhomyak.utility.kotlin_native_interop_stdlib_0.windows.zeroToWinApiErr
|
||||||
|
|
||||||
|
@Suppress("JoinDeclarationAndAssignment")
|
||||||
|
@OptIn(ExperimentalForeignApi::class, ExperimentalAtomicApi::class)
|
||||||
|
internal class ThreadLocalVariable {
|
||||||
|
private val _windows_tls_index: DWORD
|
||||||
|
private val _garbageCollectionDisabler: StableRef<ThreadLocalVariable>
|
||||||
|
private val _state: CloseableState.AllowsConcurrency
|
||||||
|
|
||||||
|
init {
|
||||||
|
this._state = OwnedUsagesCounter(this)
|
||||||
|
this._garbageCollectionDisabler = StableRef.create(this)
|
||||||
|
safeAutoClose2(
|
||||||
|
action = {
|
||||||
|
this._windows_tls_index = TlsAlloc()
|
||||||
|
if (this._windows_tls_index == TLS_OUT_OF_INDEXES)
|
||||||
|
WindowsApiException.throwFromLastWindowsErr()
|
||||||
|
},
|
||||||
|
onError = { this._garbageCollectionDisabler.dispose() }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun dealloc() {
|
||||||
|
@OptIn(ManualStateManipulation::class)
|
||||||
|
this._state.close()
|
||||||
|
|
||||||
|
zeroToWinApiErr { TlsFree(this._windows_tls_index) }
|
||||||
|
this._garbageCollectionDisabler.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun get(): LPVOID? {
|
||||||
|
this._state.withUse {
|
||||||
|
val value = TlsGetValue(this._windows_tls_index)
|
||||||
|
val errCode = GetLastError()
|
||||||
|
if (errCode != ERROR_SUCCESS.toUInt())
|
||||||
|
WindowsApiException.throwFromWindowsErrCode(errCode)
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun set(value: LPVOID?) {
|
||||||
|
this._state.withUse {
|
||||||
|
zeroToWinApiErr { TlsSetValue(this._windows_tls_index, value) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user