| // TARGET_BACKEND: NATIVE | |
| // EXIT_CODE: 99 | |
| // OUTPUT_REGEX: .*Reporting error![\r\n]+ | |
| // MODULE: cinterop | |
| // FILE: concurrentTerminate.def | |
| package async | |
| --- | |
| int test_ConcurrentTerminate(); | |
| // FILE: async.h | |
| #ifdef __cplusplus | |
| extern "C" { | |
| #endif | |
| int test_ConcurrentTerminate(); | |
| #ifdef __cplusplus | |
| } | |
| #endif | |
| // FILE: async.cpp | |
| #include <thread> | |
| #include <future> | |
| #include <chrono> | |
| #include <vector> | |
| #include <csignal> // signal.h | |
| #include "async.h" | |
| int test_ConcurrentTerminate() { | |
| signal(SIGABRT, *[](int){ exit(99); }); // Windows does not have sigaction | |
| std::vector<std::future<void>> futures; | |
| #ifdef __linux__ | |
| // TODO: invalid terminate handler called from bridge on non-main thread on Linux X64 | |
| throw std::runtime_error("Reporting error!"); | |
| #endif | |
| for (size_t i = 0; i < 100; ++i) { | |
| futures.emplace_back(std::async(std::launch::async, | |
| [](size_t param) { | |
| std::this_thread::sleep_for(std::chrono::milliseconds(param)); | |
| throw std::runtime_error("Reporting error!"); | |
| }, | |
| 200 - i)); | |
| } | |
| for (auto &future : futures) future.get(); | |
| return 0; | |
| } | |
| // MODULE: main(cinterop) | |
| // FILE: main.kt | |
| @file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class) | |
| import async.* | |
| import kotlinx.cinterop.* | |
| fun main() { | |
| test_ConcurrentTerminate() | |
| println("This is not expected.") | |
| } |