Trying to use port audio and threads, and noticed when --threads:on is set, the callbacks don't get called.
Simplest repro is the portaudio library example
nim c -r saw_out.nim
works for me
nim c -r --threads:on saw_out.nim
no sound, callback is not getting called at all, and the StopStream hangs indefinitely. This is on OSX.
I would love to understand what's going on here :)
Maybe not the most helpful comment, but I can confirm that this works without problems on Linux. I only have to increase the buffer size to avoid underruns -- but has nothing to do with threads:on. In a more complex scenario, it's important to call system.setupForeignGc() at the top of the callback to get proper GC. But the saw_out example does not require GC in the callback, so won't help either.
To track down the problem it would be interesting to build a minimal C example which sets up a p-thread like portaudio does, and calls a callback. If this minimal example fails as well, we would at least have something clear to work on (=> issue tracker).
Good idea. Here's my attempt at this
Does seem to reproduce the same issue:
$ nim c -r repro.nim
Will it work?
It worked!
$ nim c -r --threads:on repro.nim
Will it work?
<hangs indefinitely>
See anything I'm missing? If not I'll figure out how to file as an issue.
Bluenote was right.
In case anybody finds this in the future: I opened an issue and the answer was "Use and read about setupForeignThreadGc." Once you call that function, the compiler tells you you have to turn --tlsEmulation:off, and once you do that the code works.
I'm still curious about how this all works. I found a bit of info in the docs which does say that you must call setupForeignThreadGc or the GC may cause a crash. In my example it seems like this is true even if you aren't obviously using the GC, and it might cause a hang instead of a crash.
In the nimc docs I found tlsEmulation stands for Thread Local Storage emulation, but that's all I know. Looks like something gcc does sometimes? What happens when it gets turned off, does that mean pthreads tls doesn't work? Would be interested from a learning-how-all-this-works perspective.
Finally: it kind of sucks that the code needs to be different to work in threaded vs. non threaded modes. It's fair that if you want to interface with c, you have to be willing to understand a bit more of how the memory management sausage is made. But as a new user, it feels strange that the default mode of Nim is non-threaded, and that turning on thread support (with no other change) breaks my code that interfaces with c in unexpected, non-obvious ways.
But as a new user, it feels strange that the default mode of Nim is non-threaded, and that turning on thread support (with no other change) breaks my code that interfaces with c in unexpected, non-obvious ways.
Well the library you use calls your code from a different thread, so --threads:off was a lie as far as the compiler is concerned. I don't know what we can do to improve the situation except that of course --threads:on will eventually be the default as more and more code runs multithreaded.
Oh and and one more note: If the callback that you pass to C that then runs in a different thread is not declared as .gcsafe or .thread in the wrapper, the wrapper is broken.
Thank you.
--threads:on will eventually be the default
Makes sense.
the wrapper is broken.
Good to know. Once I wrap my head around this better I'll try to contribute a fix.
Hello,
3 years after, nim-portaudio isn't available anymore. Project seems to be remove on Bitbucket.
Does anyone has copy and can upload project to another git ?