diff --git a/dlls/kernel32/thread.c b/dlls/kernel32/thread.c index 4f2594cbae4..cdbe1e129f2 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 hProcess, SECURITY_ATTRIBUTES *sa, SIZE 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 hProcess, SECURITY_ATTRIBUTES *sa, SIZE 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 hProcess, SECURITY_ATTRIBUTES *sa, SIZE } else { - RtlFreeHeap( GetProcessHeap(), 0, info ); SetLastError( RtlNtStatusToDosError(status) ); handle = 0; } diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index 4d991958490..b06d1a3e149 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 @@ -348,6 +349,47 @@ static PUNHANDLED_EXCEPTION_FILTER get_unhandled_exception_filter(void) return unhandled_exception_filter; } +/*********************************************************************** + * 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 * @@ -397,7 +439,7 @@ static void start_thread( struct wine_pthread_thread_info *info ) { __TRY { - MODULE_DllThreadAttach( NULL ); + call_thread_func( func, arg ); } __EXCEPT(get_unhandled_exception_filter()) { @@ -406,9 +448,7 @@ static void start_thread( struct wine_pthread_thread_info *info ) __ENDTRY } else - MODULE_DllThreadAttach( NULL ); - - func( arg ); + call_thread_func( func, arg ); }