From 8dac3bf3b10406d05c4d520e81082e490e3b76ff Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sat, 25 Jun 2016 10:40:33 -0300 Subject: [PATCH] Added function to notify ScriptLanguage when a thread is created/freed, allows scripts to allocate a stack there via TLS --- core/os/thread.h | 7 ++++--- core/script_language.cpp | 16 ++++++++++++++++ core/script_language.h | 10 +++++++++- drivers/unix/thread_posix.cpp | 7 +++++++ drivers/windows/thread_windows.cpp | 9 ++++++++- platform/android/thread_jandroid.cpp | 3 +++ platform/winrt/thread_winrt.cpp | 2 ++ 7 files changed, 49 insertions(+), 5 deletions(-) diff --git a/core/os/thread.h b/core/os/thread.h index 7349b83dbc0..5f0ec707f22 100644 --- a/core/os/thread.h +++ b/core/os/thread.h @@ -39,6 +39,8 @@ typedef void (*ThreadCreateCallback)(void *p_userdata); + + class Thread { public: @@ -65,15 +67,14 @@ protected: static void (*wait_to_finish_func)(Thread*); static Error (*set_name_func)(const String&); - friend class Main; + friend class Main; - static ID _main_thread_id; + static ID _main_thread_id; Thread(); public: - virtual ID get_ID() const=0; static Error set_name(const String &p_name); diff --git a/core/script_language.cpp b/core/script_language.cpp index 68a694398a0..466242d39d4 100644 --- a/core/script_language.cpp +++ b/core/script_language.cpp @@ -102,6 +102,22 @@ bool ScriptServer::is_reload_scripts_on_save_enabled() { return reload_scripts_on_save; } +void ScriptServer::thread_enter() { + + for(int i=0;i<_language_count;i++) { + _languages[i]->thread_enter(); + } +} + +void ScriptServer::thread_exit() { + + for(int i=0;i<_language_count;i++) { + _languages[i]->thread_exit(); + } + +} + + void ScriptInstance::get_property_state(List > &state) { List pinfo; diff --git a/core/script_language.h b/core/script_language.h index bde4d619ab2..de725d8d082 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -59,6 +59,9 @@ public: static void set_reload_scripts_on_save(bool p_enable); static bool is_reload_scripts_on_save_enabled(); + static void thread_enter(); + static void thread_exit(); + static void init_languages(); }; @@ -128,7 +131,6 @@ public: virtual void call_multilevel_reversed(const StringName& p_method,const Variant** p_args,int p_argcount); virtual void notification(int p_notification)=0; - //this is used by script languages that keep a reference counter of their own //you can make make Ref<> not die when it reaches zero, so deleting the reference //depends entirely from the script @@ -183,6 +185,12 @@ public: virtual void auto_indent_code(String& p_code,int p_from_line,int p_to_line) const=0; virtual void add_global_constant(const StringName& p_variable,const Variant& p_value)=0; + /* MULTITHREAD FUNCTIONS */ + + //some VMs need to be notified of thread creation/exiting to allocate a stack + virtual void thread_enter() {} + virtual void thread_exit() {} + /* DEBUGGER FUNCTIONS */ virtual String debug_get_error() const=0; diff --git a/drivers/unix/thread_posix.cpp b/drivers/unix/thread_posix.cpp index 6ace64a9239..c71e09685b0 100644 --- a/drivers/unix/thread_posix.cpp +++ b/drivers/unix/thread_posix.cpp @@ -27,6 +27,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "thread_posix.h" +#include "script_language.h" #if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED) @@ -50,7 +51,13 @@ void *ThreadPosix::thread_callback(void *userdata) { ThreadPosix *t=reinterpret_cast(userdata); t->id=(ID)pthread_self(); + + ScriptServer::thread_enter(); //scripts may need to attach a stack + t->callback(t->user); + + ScriptServer::thread_exit(); + return NULL; } diff --git a/drivers/windows/thread_windows.cpp b/drivers/windows/thread_windows.cpp index d5e489aab46..434f2e8fdac 100644 --- a/drivers/windows/thread_windows.cpp +++ b/drivers/windows/thread_windows.cpp @@ -31,6 +31,7 @@ #if defined(WINDOWS_ENABLED) && !defined(WINRT_ENABLED) #include "os/memory.h" +#include "script_language.h" Thread::ID ThreadWindows::get_ID() const { @@ -45,8 +46,14 @@ Thread* ThreadWindows::create_thread_windows() { DWORD ThreadWindows::thread_callback( LPVOID userdata ) { ThreadWindows *t=reinterpret_cast(userdata); - t->callback(t->user); + + ScriptServer::thread_enter(); //scripts may need to attach a stack + t->id=(ID)GetCurrentThreadId(); // must implement + t->callback(t->user); + + ScriptServer::thread_exit(); + return 0; } diff --git a/platform/android/thread_jandroid.cpp b/platform/android/thread_jandroid.cpp index 1425e23c738..61ee237586d 100644 --- a/platform/android/thread_jandroid.cpp +++ b/platform/android/thread_jandroid.cpp @@ -29,6 +29,7 @@ #include "thread_jandroid.h" #include "os/memory.h" +#include "script_language.h" Thread::ID ThreadAndroid::get_ID() const { @@ -44,8 +45,10 @@ void *ThreadAndroid::thread_callback(void *userdata) { ThreadAndroid *t=reinterpret_cast(userdata); setup_thread(); + ScriptServer::thread_enter(); //scripts may need to attach a stack t->id=(ID)pthread_self(); t->callback(t->user); + ScriptServer::thread_exit(); return NULL; } diff --git a/platform/winrt/thread_winrt.cpp b/platform/winrt/thread_winrt.cpp index 097050e5117..e7028bd9dcc 100644 --- a/platform/winrt/thread_winrt.cpp +++ b/platform/winrt/thread_winrt.cpp @@ -33,6 +33,8 @@ Thread* ThreadWinrt::create_func_winrt(ThreadCreateCallback p_callback,void *p_user,const Settings&) { ThreadWinrt* thread = memnew(ThreadWinrt); + + std::thread new_thread(p_callback, p_user); std::swap(thread->thread, new_thread);