vushu / raylib-raku

Raylib bindings for raku
Artistic License 2.0
8 stars 3 forks source link

Callbacks with foreign threads #2

Open patrickbkr opened 9 months ago

patrickbkr commented 9 months ago

Hey! I just read this paragraph in the README:

Problem on some callbacks

example for set-audio-stream-callback: the following happens:

MoarVM panic: native callback ran on thread (some-thread-id) unknown to MoarVM

Solution yet to be found.

help is appreciated!

I've stumbled over this myself in the past. The cause is that the outside C code (raylib in this case) spawns a new thread and then calls into MoarVM with that thread. MoarVM has a management datastructure associated with every thread it knows about. It detects that this thread is unknown and then throws that error.

There is a work around and a clean solution.

Workaround

Implement a mechanism on the C side to move the call over to a thread that MoarVM knows about. That works by having a MoarVM spawned thread wait on a mutex. In the raylib callback you save the data you need to pass to some variable and then signal that mutex. The MoarVM known thread then picks up that data and uses it.

Clean solution

This issue can be fixed once and for all by teaching MoarVM to not die when an unknown thread is seen, but instead set up the management datastructure for it and then happily proceed. This is simply Not Yet Implemented. Jnthn, the MoarVM architect has confirmed that this the way to do it and it shouldn't be terribly difficult to do. (For some value of terrible.)

vushu commented 9 months ago

Hi @patrickbkr, thanks for the suggestions 😊. I'm not sure how to do the workaround I think it would be way too cumbersome, since raylib relies on miniaudio which does the threading for audio so I need to tweak both raylib and miniaudio's code to make the workaround. I definitely prefer the clean solution where Moarvm handles this and I would love to implement this, but I sadly have no knowledge about the VM😅

Xliff commented 8 months ago

@patrickbkr - Oh thanks for mentioning the workaround. I may see if I can write a formal implementation on that for GStreamer