Module: wine Branch: master Commit: 7a383cf83f1f2896f67352a76c07b13510baff1d URL: http://source.winehq.org/git/wine.git/?a=commit;h=7a383cf83f1f2896f67352a76c...
Author: Alexandre Julliard julliard@winehq.org Date: Thu Jan 18 15:02:11 2007 +0100
ntdll: Abuse RtlCreateUserThread to call the thread function for CreateThread directly.
---
dlls/kernel32/thread.c | 49 +----------------------------------------------- dlls/ntdll/thread.c | 48 +++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 52 deletions(-)
diff --git a/dlls/kernel32/thread.c b/dlls/kernel32/thread.c index 4f2594c..cdbe1e1 100644 --- a/dlls/kernel32/thread.c +++ b/dlls/kernel32/thread.c @@ -45,42 +45,6 @@ #include "kernel_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(thread); -WINE_DECLARE_DEBUG_CHANNEL(relay); - - -struct new_thread_info -{ - LPTHREAD_START_ROUTINE func; - void *arg; -}; - - -/*********************************************************************** - * THREAD_Start - * - * Start execution of a newly created thread. Does not return. - */ -static void CALLBACK THREAD_Start( void *ptr ) -{ - struct new_thread_info *info = ptr; - LPTHREAD_START_ROUTINE func = info->func; - void *arg = info->arg; - - RtlFreeHeap( GetProcessHeap(), 0, info ); - - if (TRACE_ON(relay)) - DPRINTF("%04x:Starting thread (entryproc=%p)\n", GetCurrentThreadId(), func ); - - __TRY - { - ExitThread( func( arg ) ); - } - __EXCEPT(UnhandledExceptionFilter) - { - TerminateThread( GetCurrentThread(), GetExceptionCode() ); - } - __ENDTRY -}
/*********************************************************************** @@ -120,22 +84,13 @@ HANDLE WINAPI CreateRemoteThread( HANDLE CLIENT_ID client_id; NTSTATUS status; SIZE_T stack_reserve = 0, stack_commit = 0; - struct new_thread_info *info; - - if (!(info = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*info) ))) - { - SetLastError( ERROR_NOT_ENOUGH_MEMORY ); - return 0; - } - info->func = start; - info->arg = param;
if (flags & STACK_SIZE_PARAM_IS_A_RESERVATION) stack_reserve = stack; else stack_commit = stack;
status = RtlCreateUserThread( hProcess, NULL, TRUE, NULL, stack_reserve, stack_commit, - THREAD_Start, info, &handle, &client_id ); + (PRTL_THREAD_START_ROUTINE)start, param, &handle, &client_id ); if (status == STATUS_SUCCESS) { if (id) *id = (DWORD)client_id.UniqueThread; @@ -147,7 +102,6 @@ HANDLE WINAPI CreateRemoteThread( HANDLE if (NtResumeThread( handle, &ret )) { NtClose( handle ); - RtlFreeHeap( GetProcessHeap(), 0, info ); SetLastError( ERROR_NOT_ENOUGH_MEMORY ); handle = 0; } @@ -155,7 +109,6 @@ HANDLE WINAPI CreateRemoteThread( HANDLE } else { - RtlFreeHeap( GetProcessHeap(), 0, info ); SetLastError( RtlNtStatusToDosError(status) ); handle = 0; } diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index 4d99195..b06d1a3 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -43,6 +43,7 @@ #include "wine/exception.h"
WINE_DEFAULT_DEBUG_CHANNEL(thread); +WINE_DECLARE_DEBUG_CHANNEL(relay);
/* info passed to a starting thread */ struct startup_info @@ -349,6 +350,47 @@ static PUNHANDLED_EXCEPTION_FILTER get_u }
/*********************************************************************** + * call_thread_func + * + * Hack to make things compatible with the thread procedures used by kernel32.CreateThread. + */ +static void DECLSPEC_NORETURN call_thread_func( PRTL_THREAD_START_ROUTINE rtl_func, void *arg ) +{ + LPTHREAD_START_ROUTINE func = (LPTHREAD_START_ROUTINE)rtl_func; + DWORD exit_code; + BOOL last; + + MODULE_DllThreadAttach( NULL ); + + if (TRACE_ON(relay)) + DPRINTF( "%04x:Starting thread proc %p (arg=%p)\n", GetCurrentThreadId(), func, arg ); + + exit_code = func( arg ); + + /* send the exit code to the server */ + SERVER_START_REQ( terminate_thread ) + { + req->handle = GetCurrentThread(); + req->exit_code = exit_code; + wine_server_call( req ); + last = reply->last; + } + SERVER_END_REQ; + + if (last) + { + LdrShutdownProcess(); + exit( exit_code ); + } + else + { + LdrShutdownThread(); + server_exit_thread( exit_code ); + } +} + + +/*********************************************************************** * start_thread * * Startup routine for a newly created thread. @@ -397,7 +439,7 @@ static void start_thread( struct wine_pt { __TRY { - MODULE_DllThreadAttach( NULL ); + call_thread_func( func, arg ); } __EXCEPT(get_unhandled_exception_filter()) { @@ -406,9 +448,7 @@ static void start_thread( struct wine_pt __ENDTRY } else - MODULE_DllThreadAttach( NULL ); - - func( arg ); + call_thread_func( func, arg ); }