Module: wine Branch: master Commit: 53e4c36ef8c0720b61b03bb40d5992225c2771f3 URL: http://source.winehq.org/git/wine.git/?a=commit;h=53e4c36ef8c0720b61b03bb40d...
Author: Alexandre Julliard julliard@winehq.org Date: Wed Nov 29 19:42:53 2017 +0100
ntdll: Add a platform-specific helper for starting a thread.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ntdll/ntdll_misc.h | 1 + dlls/ntdll/signal_arm.c | 31 +++++++++++++++++++++++++++++++ dlls/ntdll/signal_arm64.c | 31 +++++++++++++++++++++++++++++++ dlls/ntdll/signal_i386.c | 35 +++++++++++++++++++++++++++++++++-- dlls/ntdll/signal_powerpc.c | 31 +++++++++++++++++++++++++++++++ dlls/ntdll/signal_x86_64.c | 31 +++++++++++++++++++++++++++++++ dlls/ntdll/thread.c | 23 +++-------------------- 7 files changed, 161 insertions(+), 22 deletions(-)
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index cab8d6d..d3a37e8 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -68,6 +68,7 @@ extern NTSTATUS signal_alloc_thread( TEB **teb ) DECLSPEC_HIDDEN; extern void signal_free_thread( TEB *teb ) DECLSPEC_HIDDEN; extern void signal_init_thread( TEB *teb ) DECLSPEC_HIDDEN; extern void signal_init_process(void) DECLSPEC_HIDDEN; +extern NTSTATUS signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg ) DECLSPEC_HIDDEN; extern NTSTATUS signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend ) DECLSPEC_HIDDEN; extern void version_init( const WCHAR *appname ) DECLSPEC_HIDDEN; extern void debug_init(void) DECLSPEC_HIDDEN; diff --git a/dlls/ntdll/signal_arm.c b/dlls/ntdll/signal_arm.c index 2a68946..3ff8c91 100644 --- a/dlls/ntdll/signal_arm.c +++ b/dlls/ntdll/signal_arm.c @@ -62,6 +62,7 @@ #include "winnt.h"
WINE_DEFAULT_DEBUG_CHANNEL(seh); +WINE_DECLARE_DEBUG_CHANNEL(relay);
static pthread_key_t teb_key;
@@ -1012,6 +1013,36 @@ void signal_init_process(void) }
+struct startup_info +{ + LPTHREAD_START_ROUTINE entry; + void *arg; +}; + +static void thread_startup( void *param ) +{ + struct startup_info *info = param; + call_thread_entry_point( info->entry, info->arg ); +} + + +/*********************************************************************** + * signal_start_thread + */ +NTSTATUS signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg ) +{ + NTSTATUS status; + struct startup_info info = { entry, arg }; + + if (!(status = wine_call_on_stack( attach_dlls, (void *)1, NtCurrentTeb()->Tib.StackBase ))) + { + TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg ); + wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase ); + } + return status; +} + + /********************************************************************** * signal_start_process */ diff --git a/dlls/ntdll/signal_arm64.c b/dlls/ntdll/signal_arm64.c index d1e4021..e0e424e 100644 --- a/dlls/ntdll/signal_arm64.c +++ b/dlls/ntdll/signal_arm64.c @@ -59,6 +59,7 @@ #include "winnt.h"
WINE_DEFAULT_DEBUG_CHANNEL(seh); +WINE_DECLARE_DEBUG_CHANNEL(relay);
static pthread_key_t teb_key;
@@ -883,6 +884,36 @@ void signal_init_process(void) }
+struct startup_info +{ + LPTHREAD_START_ROUTINE entry; + void *arg; +}; + +static void thread_startup( void *param ) +{ + struct startup_info *info = param; + call_thread_entry_point( info->entry, info->arg ); +} + + +/*********************************************************************** + * signal_start_thread + */ +NTSTATUS signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg ) +{ + NTSTATUS status; + struct startup_info info = { entry, arg }; + + if (!(status = wine_call_on_stack( attach_dlls, (void *)1, NtCurrentTeb()->Tib.StackBase ))) + { + TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg ); + wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase ); + } + return status; +} + + /*********************************************************************** * start_process */ diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c index 7914ff5..074ad3b 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -69,6 +69,9 @@
#undef ERR /* Solaris needs to define this */
+WINE_DEFAULT_DEBUG_CHANNEL(seh); +WINE_DECLARE_DEBUG_CHANNEL(relay); + /* not defined for x86, so copy the x86_64 definition */ typedef struct DECLSPEC_ALIGN(16) _M128A { @@ -468,8 +471,6 @@ typedef struct trapframe ucontext_t; #error You must define the signal context functions for your platform #endif /* linux */
-WINE_DEFAULT_DEBUG_CHANNEL(seh); - typedef int (*wine_signal_handler)(unsigned int sig);
static const size_t teb_size = 4096; /* we reserve one page for the TEB */ @@ -2601,6 +2602,36 @@ void signal_init_process(void) }
+struct startup_info +{ + LPTHREAD_START_ROUTINE entry; + void *arg; +}; + +static void thread_startup( void *param ) +{ + struct startup_info *info = param; + call_thread_entry_point( info->entry, info->arg ); +} + + +/*********************************************************************** + * signal_start_thread + */ +NTSTATUS signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg ) +{ + NTSTATUS status; + struct startup_info info = { entry, arg }; + + if (!(status = wine_call_on_stack( attach_dlls, (void *)1, NtCurrentTeb()->Tib.StackBase ))) + { + TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg ); + wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase ); + } + return status; +} + + /********************************************************************** * signal_start_process */ diff --git a/dlls/ntdll/signal_powerpc.c b/dlls/ntdll/signal_powerpc.c index 209339a..c5b3fdb 100644 --- a/dlls/ntdll/signal_powerpc.c +++ b/dlls/ntdll/signal_powerpc.c @@ -59,6 +59,7 @@ #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(seh); +WINE_DECLARE_DEBUG_CHANNEL(relay);
static pthread_key_t teb_key;
@@ -1085,6 +1086,36 @@ void signal_init_process(void) }
+struct startup_info +{ + LPTHREAD_START_ROUTINE entry; + void *arg; +}; + +static void thread_startup( void *param ) +{ + struct startup_info *info = param; + call_thread_entry_point( info->entry, info->arg ); +} + + +/*********************************************************************** + * signal_start_thread + */ +NTSTATUS signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg ) +{ + NTSTATUS status; + struct startup_info info = { entry, arg }; + + if (!(status = wine_call_on_stack( attach_dlls, (void *)1, NtCurrentTeb()->Tib.StackBase ))) + { + TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg ); + wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase ); + } + return status; +} + + /*********************************************************************** * start_process */ diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c index b81bfc0..024af8e 100644 --- a/dlls/ntdll/signal_x86_64.c +++ b/dlls/ntdll/signal_x86_64.c @@ -73,6 +73,7 @@ #endif
WINE_DEFAULT_DEBUG_CHANNEL(seh); +WINE_DECLARE_DEBUG_CHANNEL(relay);
struct _DISPATCHER_CONTEXT;
@@ -3143,6 +3144,36 @@ void signal_init_process(void) }
+struct startup_info +{ + LPTHREAD_START_ROUTINE entry; + void *arg; +}; + +static void thread_startup( void *param ) +{ + struct startup_info *info = param; + call_thread_entry_point( info->entry, info->arg ); +} + + +/*********************************************************************** + * signal_start_thread + */ +NTSTATUS signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg ) +{ + NTSTATUS status; + struct startup_info info = { entry, arg }; + + if (!(status = wine_call_on_stack( attach_dlls, (void *)1, NtCurrentTeb()->Tib.StackBase ))) + { + TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg ); + wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase ); + } + return status; +} + + /********************************************************************** * signal_start_process */ diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index 80f4780..18d0fe1 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -47,7 +47,6 @@ #include "wine/exception.h"
WINE_DEFAULT_DEBUG_CHANNEL(thread); -WINE_DECLARE_DEBUG_CHANNEL(relay);
struct _KUSER_SHARED_DATA *user_shared_data = NULL;
@@ -491,29 +490,13 @@ void exit_thread( int status )
/*********************************************************************** - * thread_startup - */ -static void thread_startup( void *param ) -{ - struct startup_info *info = param; - PRTL_THREAD_START_ROUTINE func = info->entry_point; - void *arg = info->entry_arg; - - attach_dlls( (void *)1 ); - - TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", func, arg ); - - call_thread_entry_point( (LPTHREAD_START_ROUTINE)func, arg ); -} - - -/*********************************************************************** * start_thread * * Startup routine for a newly created thread. */ static void start_thread( struct startup_info *info ) { + NTSTATUS status; TEB *teb = info->teb; struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)&teb->GdiTebBatch; struct debug_info debug_info; @@ -525,8 +508,8 @@ static void start_thread( struct startup_info *info )
signal_init_thread( teb ); server_init_thread( info->entry_point ); - - wine_switch_to_stack( thread_startup, info, teb->Tib.StackBase ); + status = signal_start_thread( (LPTHREAD_START_ROUTINE)info->entry_point, info->entry_arg ); + NtTerminateThread( GetCurrentThread(), status ); }