ntdll: Add a platform-specific helper for starting a thread.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2017-11-29 19:42:53 +01:00
parent afb16abc0f
commit 53e4c36ef8
7 changed files with 161 additions and 22 deletions

View file

@ -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;

View file

@ -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
*/

View file

@ -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
*/

View file

@ -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
*/

View file

@ -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
*/

View file

@ -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
*/

View file

@ -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;
@ -490,23 +489,6 @@ 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
*
@ -514,6 +496,7 @@ static void thread_startup( void *param )
*/
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 );
}