From 7f32023a1ac60b62bd0159a542c25fdad0864dba Mon Sep 17 00:00:00 2001 From: Ruslan Mustakov Date: Wed, 26 Jul 2017 15:58:12 +0700 Subject: 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. --- modules/nativescript/nativescript.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'modules/nativescript/nativescript.h') diff --git a/modules/nativescript/nativescript.h b/modules/nativescript/nativescript.h index bc7a6e3ed6..cf3a64e9b8 100644 --- a/modules/nativescript/nativescript.h +++ b/modules/nativescript/nativescript.h @@ -41,6 +41,10 @@ #include "godot_nativescript.h" #include "modules/gdnative/gdnative.h" +#ifndef NO_THREADS +#include "os/mutex.h" +#endif + struct NativeScriptDesc { struct Method { @@ -197,6 +201,19 @@ private: void _unload_stuff(); +#ifndef NO_THREADS + Mutex *mutex; + + Set > libs_to_init; + Set scripts_to_register; + volatile bool has_objects_to_register; // so that we don't lock mutex every frame - it's rarely needed + void defer_init_library(Ref lib, NativeScript *script); +#endif + + void init_library(const Ref &lib); + void register_script(NativeScript *script); + void unregister_script(NativeScript *script); + public: Map > library_classes; Map > library_gdnatives; @@ -206,6 +223,10 @@ public: const StringName _init_call_type = "nativescript_init"; const StringName _init_call_name = "godot_nativescript_init"; + const StringName _thread_cb_call_type = "godot_nativescript_thread_cb"; + const StringName _thread_enter_call_name = "godot_nativescript_thread_enter"; + const StringName _thread_exit_call_name = "godot_nativescript_thread_exit"; + NativeScriptLanguage(); ~NativeScriptLanguage(); @@ -215,6 +236,13 @@ public: void _hacky_api_anchor(); +#ifndef NO_THREADS + virtual void thread_enter(); + virtual void thread_exit(); + + virtual void frame(); +#endif + virtual String get_name() const; virtual void init(); virtual String get_type() const; -- cgit v1.2.3