How do I react to a SIGINT event in Kotlin Native?
# kotlin-native
p
How do I react to a SIGINT event in Kotlin Native?
m
You would do it like in C++: with a call to the
signal
method you can define a sigint handler, like described here: https://www.tutorialspoint.com/cplusplus/cpp_signal_handling.htm
If you type
signal
in your Kotlin Native project, IntelliJ will suggest you import
platform.posix.signal
(SIGINT, exit, etc. are also there):
message has been deleted
Now we need to figure out how to pass a Kotlin function as a CPointer/CFunction - that’s described here: https://kotlinlang.org/docs/tutorials/native/mapping-function-pointers-from-c.html
Here’s a small code snippet I came up with that never stops, and SIGINT is used to do something (last resort) and then exit the program (although it doesn’t have to quit the program here):
Now we can compile the program with
kotlinc-native sigint.kt -o sigint
and run it with
./sigint.kexe
- this will run forever, unless we send SIGTERM via:
killall -SIGINT sigint.kexe
Then the handler function will be called 🙂
p
Hey Marc, thanks for replying. Your suggestion works well! The only problem I have now is that I can't call any library code inside the handleSigint function. All of the code in there is just ignored, except for the exit() and println() functions. Do you have any idea what the problem might be?
The description of the function sounds like you cannot use any Kotlin variables in the static function, is that correct?
m
Hey Patrick! I can’t reproduce your problem - I just defined another function that creates a random list, sorts it and prints its items, and I can call that fine from the handler function. The Kotlin function itself is just that - a regular function. We only create a static C reference to that function and pass it to the
signal
method - but how the function itself is implemented shouldn’t matter.
I suggest you try to do the most simple thing in that function first - and check if that runs. Then continue with the next small step. What happens if you just create another method in the same file and try to call that?
p
Interesting, I can definitely reproduce the problem on my side. I will try the approach you suggested and report back.
Could be a memory problem, maybe the object is null if you call it that way.
d
How are you passing the object function?
p
I defined it outside of the main function as a global variable.
d
Have you done it this way?
Copy code
staticCFunction { MyObject.handleSigint(....) }
Explicitly specifying the object class and doing it in a lambda (not a method reference).
p
I did it like this
How do I call Library code from the handleSigInt function? Is there a way to pass parameters to it?
d
Oh. That looks correct then. Are you sure it's not being called? Have you tried
println
and stuff?
p
Let me do some additional tests, I'll report back.
Ok I think it has something to do with coroutines. My whole code runs in a runBlocking block, but if I instantiate the object outside of that block, will it still be available to the coroutine?
But you are right, I can call library methods like that, but there seems to be some issues if the code runs inside a coroutine.
Ok maybe it's a problem with threading. I've had another look at the C interop documentation and it mentions that you have to call
kotlin.native.initRuntimeIfNeeded()
if your callback is called on another thread. Could that be the issue?
d
Ha! Yeah probably. Forgot about that.
p
Do you know where I have to call it? At the beginning of the staticCFunction?
d
Yes, inside the static c function, before Kotlin is touched.
p
Ok so I guess right as the first thing?
Because I tried that and it still doesn't seem to work
d
Hmm, then I'm not sure.
p
Maybe it's a bug in combination with coroutines. I just don't know where to start to debug that thing.