Bluenote was right.

In case anybody finds this in the future: I opened an 
[issue](https://github.com/nim-lang/Nim/issues/5381) 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](https://nim-lang.org/0.13.0/backends.html#memory-management-thread-coordination)
 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](https://nim-lang.org/docs/nimc.html) I found tlsEmulation 
stands for [Thread Local 
Storage](https://en.wikipedia.org/wiki/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.

Reply via email to