The lede:
Can I, for instance, safely call Fiber.yield in a C callback that I know will be run in a Fiber?
The stack will look like:
Thread
|- Fiber in D runtime
| |- Call into a C API (stays on same thread)
| | |- Extern (C) callback (stays on same thread)
| | | |- Fiber.yield <-- Is this OK?
Also, in general, is there a convenient way to know or test if particular C callbacks are safe? Or is it just case by case?
The context I was gonna bury the lede in but thought better of it:
So, I am a big lame novice. Don't worry, I know this already.
I'm trying to use gtk-d, but I don't even know how to use gtk, so I'm learning them both at once. Probably not a good idea, I know.
From what I can tell so far, it seems like the way gtk works is you write your whole application in terms of gtk's event loop. I really don't want to do that, so -- and I realize this is probably an even worse idea, but I don't know the right thing to do -- I decided I'd try writing a worker thread class -- "Rope" -- and run gtk's event loop in a Rope.
A Rope runs its given task in a new Fiber in a new thread, and that thread repeatedly resumes the fiber and terminates when the fiber terminates, but, in the meantime, takes some time to act as an executor each time the fiber suspends, accepting work in std.concurrency messages and running it on the same thread as its main fiber. My thought was that this way, I can call gtk-d's API from any thread, and still have all the calls happen on the same thread that the event loop is running on, as the API requires.
All I needed, then, was some way to make gtk-d suspend the fiber it's running on, to give its rope some time to service external work. My first thought was to use glib.Timeout.Timeout.add and put Fiber.yield in the timeout callback. The potential problem: the timeout callback, of course, has to be extern (C).
Now, I could just drop the more general concept of Rope and rewrite it specifically for gtk, and drop the whole Fiber part, and instead directly put the calls to std.concurrency.receiveTimeout in the glib.Timeout.Timeout.add callback. Assuming, of course, receiveTimeout would be any safer to call from extern (C) than Fiber.yield would. But that's just the trouble, I can't guess which would be safer, and even a minimal test for this question seems daunting.