onyxblade / godot-ruby

ruby language binding for godot game engine
MIT License
37 stars 2 forks source link

vm crash at calling from different thread #2

Open onyxblade opened 6 years ago

onyxblade commented 6 years ago

Ruby VM currently does not support multi-threading as a historical problem(https://bugs.ruby-lang.org/issues/14792). Any calls to the vm in a thread other than where ruby_init() occurred will fail.

However godot uses multiple threads to call pluginscript callbacks. I don't know if there are options to control this behaviour.

One possible solution is to switch to mruby. Hope it doesn't require much work.

ForeverZer0 commented 4 years ago

Ruby most definitely does support multi-threading, it is just clunky to use correctly, but to be fair, all mutli-threading code in C is.

Include the <ruby/thread.h> header, and you will have some functions for multi-threading, specifically rb_thread_call_without_gvl, and rb_thread_call_with_gvl to get around the global VM lock. Note that this is only needed for invoking Ruby API functions, not necessarily all of your code, where normal multi-threading idioms using a mutex, etc. would still need followed.

There is an obvious cost to unlocking and reacquiring the GVL, which makes the viability of Ruby as a scripting language still questionable, but the functionality to do so is there.

onyxblade commented 2 years ago

Hi @ForeverZer0,

Thanks for commenting, and sorry for the late reply. I think the rb_thread_call_without_gvl is used within a ruby thread to run non-blocking C functions, but it cannot help prevent the segfault produced by accessing the vm from different native threads.

A simple snippet demonstrating this issue is https://github.com/onyxblade/tricks/blob/master/ruby-thread-test/ruby.c . Godot accesses the vm randomly from different threads. We cannot even know the thread id since no threading related hooks are exposed in pluginscript: https://github.com/godotengine/godot/blob/master/modules/gdnative/pluginscript/pluginscript_language.h#L91 .

I would consider it a bug of pluginscript because the api exposed is supposed to be on single thread, but the script editor might actually access from multiple threads.