diff options
| author | Ruslan Mustakov | 2017-07-26 15:58:12 +0700 |
|---|---|---|
| committer | Ruslan Mustakov | 2017-07-26 19:39:10 +0700 |
| commit | 7f32023a1ac60b62bd0159a542c25fdad0864dba (patch) | |
| tree | 8d0bf427ab1c4aa1839479cfe881f6fdca38ef8a /modules/nativescript/register_types.cpp | |
| parent | f55211ae0dc202cc015c247495af8e05af81b24b (diff) | |
| download | godot-7f32023a1ac60b62bd0159a542c25fdad0864dba.tar.gz godot-7f32023a1ac60b62bd0159a542c25fdad0864dba.tar.zst godot-7f32023a1ac60b62bd0159a542c25fdad0864dba.zip | |
Support multithreading for NativeScriptLanguage
Godot may call property setters from non-main thread when an object is
loaded in the edtior. This means NativeScriptLanguage could be accessed
from different threads, but it was not designed for thread-safety.
Besides, previous behaviour made it so that godot_nativescript_init and
godot_gdnative_init could be invoked from non-main thread, while
godot_gdnative_thread is always invoked on the main thread. This may
not be expected by the binding library.
This commit defers native library initialization to the main thread and
adds godot_nativescript_thread_enter and godot_nativescript_thread_exit
callbacks to make a binding library aware of foreign threads.
Diffstat (limited to 'modules/nativescript/register_types.cpp')
| -rw-r--r-- | modules/nativescript/register_types.cpp | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/modules/nativescript/register_types.cpp b/modules/nativescript/register_types.cpp index 6c88b04a5..a8a931343 100644 --- a/modules/nativescript/register_types.cpp +++ b/modules/nativescript/register_types.cpp @@ -61,6 +61,32 @@ void init_call_cb(void *p_handle, godot_string *p_proc_name, void *p_data, int p fn(args[0]); } +#ifndef NO_THREADS + +typedef void (*native_script_empty_callback)(); + +void thread_call_cb(void *p_handle, godot_string *p_proc_name, void *p_data, int p_num_args, void **args, void *r_ret) { + if (p_handle == NULL) { + ERR_PRINT("No valid library handle, can't call nativescript thread enter/exit callback"); + return; + } + + void *library_proc; + Error err = OS::get_singleton()->get_dynamic_library_symbol_handle( + p_handle, + *(String *)p_proc_name, + library_proc); + if (err != OK) { + // it's fine if thread callbacks are not present in the library. + return; + } + + native_script_empty_callback fn = (native_script_empty_callback)library_proc; + fn(); +} + +#endif // NO_THREADS + ResourceFormatLoaderNativeScript *resource_loader_gdns = NULL; ResourceFormatSaverNativeScript *resource_saver_gdns = NULL; @@ -72,6 +98,9 @@ void register_nativescript_types() { ScriptServer::register_language(native_script_language); GDNativeCallRegistry::singleton->register_native_raw_call_type(native_script_language->_init_call_type, init_call_cb); +#ifndef NO_THREADS + GDNativeCallRegistry::singleton->register_native_raw_call_type(native_script_language->_thread_cb_call_type, thread_call_cb); +#endif resource_saver_gdns = memnew(ResourceFormatSaverNativeScript); ResourceSaver::add_resource_format_saver(resource_saver_gdns); |
