| // Cross-thread signalling does not work on Windows | |
| // DISABLE_NATIVE: targetFamily=MINGW | |
| // MODULE: cinterop | |
| // FILE: workerSignals.def | |
| --- | |
| #include <stdint.h> | |
| void setupSignalHandler(void); | |
| void signalThread(uint64_t thread, int value); | |
| int getValue(void); | |
| // FILE: workerSignals.cpp | |
| #include <cassert> | |
| #include <cstdint> | |
| #include <cstring> | |
| #include <pthread.h> | |
| #include <signal.h> | |
| namespace { | |
| int pendingValue = 0; | |
| thread_local int value = 0; | |
| void signalHandler(int signal) { | |
| value = pendingValue; | |
| } | |
| } // namespace | |
| extern "C" void setupSignalHandler(void) { | |
| signal(SIGUSR1, &signalHandler); | |
| } | |
| extern "C" void signalThread(uint64_t thread, int value) { | |
| pendingValue = value; | |
| pthread_t t = {}; | |
| memcpy(&t, &thread, sizeof(pthread_t)); | |
| auto result = pthread_kill(t, SIGUSR1); | |
| assert(result == 0); | |
| } | |
| extern "C" int getValue(void) { | |
| return value; | |
| } | |
| // MODULE: main(cinterop) | |
| // FILE: main.kt | |
| @file:OptIn(kotlin.ExperimentalStdlibApi::class, ObsoleteWorkersApi::class, kotlinx.cinterop.ExperimentalForeignApi::class) | |
| import kotlin.native.concurrent.* | |
| import kotlin.test.* | |
| import workerSignals.* | |
| const val defaultValue = 0 | |
| const val newValue = 42 | |
| fun main() { | |
| setupSignalHandler() | |
| withWorker { | |
| val before = execute(TransferMode.SAFE, {}) { | |
| getValue() | |
| }.result | |
| assertEquals(defaultValue, getValue()) | |
| assertEquals(defaultValue, before) | |
| signalThread(platformThreadId, newValue) | |
| val after = execute(TransferMode.SAFE, {}) { | |
| getValue() | |
| }.result | |
| assertEquals(defaultValue, getValue()) | |
| assertEquals(newValue, after) | |
| } | |
| } |