aboutsummaryrefslogtreecommitdiff
path: root/modules/nativescript/register_types.cpp
diff options
context:
space:
mode:
authorRuslan Mustakov2017-07-26 15:58:12 +0700
committerRuslan Mustakov2017-07-26 19:39:10 +0700
commit7f32023a1ac60b62bd0159a542c25fdad0864dba (patch)
tree8d0bf427ab1c4aa1839479cfe881f6fdca38ef8a /modules/nativescript/register_types.cpp
parentf55211ae0dc202cc015c247495af8e05af81b24b (diff)
downloadgodot-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.cpp29
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);