Explorar o código

Added function to notify ScriptLanguage when a thread is created/freed, allows scripts to allocate a stack there via TLS

Juan Linietsky %!s(int64=9) %!d(string=hai) anos
pai
achega
8dac3bf3b1

+ 4 - 3
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);

+ 16 - 0
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<Pair<StringName, Variant> > &state) {
 
 	List<PropertyInfo> pinfo;

+ 9 - 1
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;

+ 7 - 0
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<ThreadPosix*>(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;
 }
 

+ 8 - 1
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<ThreadWindows*>(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;
 }
 

+ 3 - 0
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<ThreadAndroid*>(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;
 }
 

+ 2 - 0
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);