OK, I've got it! It has _nothing_ to do with runForever() or asyncdispatch.
Here another example that crashes:
import os
proc whatever() {.thread, nimcall.} =
echo("TEST")
proc initProcessX(): void =
echo("In initProcess()")
var thread: Thread[void]
createThread(thread, whatever)
echo("initProcess() done")
proc doStuff(): void =
echo("In doStuff()")
# ...
initProcessX()
sleep(500)
# ...
echo("Crashes before getting here!")
doStuff()
And here, one that doesn't crash:
import os
var thread: Thread[void]
proc whatever() {.thread, nimcall.} =
echo("TEST")
proc initProcessX(): void =
echo("In initProcess()")
#var thread: Thread[void]
createThread(thread, whatever)
echo("initProcess() done")
proc doStuff(): void =
echo("In doStuff()")
# ...
initProcessX()
sleep(500)
# ...
echo("Crashes before getting here!")
doStuff()
It looks like the issue is that I don't have a "hard reference" to the thread
itself, so I assume it gets garbage-collected. Should I always keep a
hard-reference to threads, until they are done? Or is that a bug?
EDIT: My "real" code is still crashing after the fix I discovered, but now I'm
getting a stack-trace, so I think I should eventually work it out too:
First msg sent from Thread 0.
Thread 1 initialised.
Traceback (most recent call last)
kueues.nim(1032) runForeverThread
asyncdispatch.nim(278) runForever
asyncdispatch.nim(283) poll
Error: unhandled exception: No handles or timers registered in dispatcher.
[ValueError]
Message received after 0 'timestamp units'
Error: execution of an external program failed: '../bin/test_kueues '
The terminal process terminated with exit code: 1