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/
|
||||
build/
|
||||
|
||||
@ -22,6 +22,7 @@ version = "0.1"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven("https://maven.landgrafhomyak.ru/")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
@ -68,7 +69,13 @@ kotlin {
|
||||
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 notJvmTest by creating { dependsOn(commonTest) }
|
||||
@ -96,11 +103,13 @@ kotlin {
|
||||
this@target.compilations.getByName("main").defaultSourceSet.dependsOn(multithreadPlatformMain)
|
||||
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 {
|
||||
|
||||
@ -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