Module: wine Branch: master Commit: 1ac7bafcb248150f0ede665c26cb8c2b1fb2cb11 URL: http://source.winehq.org/git/wine.git/?a=commit;h=1ac7bafcb248150f0ede665c26...
Author: Alexandre Julliard julliard@winehq.org Date: Fri Feb 20 11:45:47 2009 +0100
ntdll: Call pthread_create and pthread_exit directly from ntdll.
---
dlls/ntdll/thread.c | 37 ++++++++++++++++++++++++++----------- 1 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index eeb98c3..e11976c 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -67,6 +67,7 @@ static RTL_BITMAP fls_bitmap; static LIST_ENTRY tls_links; static size_t sigstack_total_size; static ULONG sigstack_zero_bits; +static int nb_threads = 1;
static struct wine_pthread_functions pthread_functions;
@@ -352,12 +353,14 @@ HANDLE thread_init(void) */ void abort_thread( int status ) { + if (interlocked_xchg_add( &nb_threads, -1 ) <= 1) _exit( status ); + pthread_sigmask( SIG_BLOCK, &server_block_set, NULL ); close( ntdll_get_thread_data()->wait_fd[0] ); close( ntdll_get_thread_data()->wait_fd[1] ); close( ntdll_get_thread_data()->reply_fd ); close( ntdll_get_thread_data()->request_fd ); - pthread_functions.abort_thread( status ); + pthread_exit( UIntToPtr(status) ); }
@@ -366,8 +369,11 @@ void abort_thread( int status ) */ static void DECLSPEC_NORETURN exit_thread( int status ) { - struct wine_pthread_thread_info info; int fds[4]; + void *teb_addr; + SIZE_T teb_size; + + if (interlocked_xchg_add( &nb_threads, -1 ) <= 1) exit( status );
RtlAcquirePebLock(); RemoveEntryList( &NtCurrentTeb()->TlsLinks ); @@ -375,25 +381,24 @@ static void DECLSPEC_NORETURN exit_thread( int status ) RtlFreeHeap( GetProcessHeap(), 0, NtCurrentTeb()->FlsSlots ); RtlFreeHeap( GetProcessHeap(), 0, NtCurrentTeb()->TlsExpansionSlots );
- info.stack_base = NtCurrentTeb()->DeallocationStack; - info.teb_base = NtCurrentTeb(); - info.teb_sel = wine_get_fs(); - info.exit_status = status; - fds[0] = ntdll_get_thread_data()->wait_fd[0]; fds[1] = ntdll_get_thread_data()->wait_fd[1]; fds[2] = ntdll_get_thread_data()->reply_fd; fds[3] = ntdll_get_thread_data()->request_fd; pthread_sigmask( SIG_BLOCK, &server_block_set, NULL );
- info.stack_size = virtual_free_system_view( &info.stack_base ); - info.teb_size = virtual_free_system_view( &info.teb_base ); + virtual_free_system_view( &NtCurrentTeb()->DeallocationStack ); + teb_addr = NtCurrentTeb(); + teb_size = virtual_free_system_view( &teb_addr );
close( fds[0] ); close( fds[1] ); close( fds[2] ); close( fds[3] ); - pthread_functions.exit_thread( &info ); + + wine_ldt_free_fs( wine_get_fs() ); + if (teb_size) munmap( teb_addr, teb_size ); + pthread_exit( UIntToPtr(status) ); }
@@ -514,6 +519,8 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR * HANDLE *handle_ptr, CLIENT_ID *id ) { sigset_t sigset; + pthread_t pthread_id; + pthread_attr_t attr; struct ntdll_thread_data *thread_data = NULL; struct ntdll_thread_regs *thread_regs; struct startup_info *info = NULL; @@ -623,11 +630,19 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR * info->entry_point = start; info->entry_arg = param;
- if (pthread_functions.create_thread( &info->pthread_info ) == -1) + pthread_attr_init( &attr ); + pthread_attr_setstacksize( &attr, stack_reserve ); + pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED ); + pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ); /* force creating a kernel thread */ + interlocked_xchg_add( &nb_threads, 1 ); + if (pthread_create( &pthread_id, &attr, (void * (*)(void *))start_thread, info )) { + interlocked_xchg_add( &nb_threads, -1 ); + pthread_attr_destroy( &attr ); status = STATUS_NO_MEMORY; goto error; } + pthread_attr_destroy( &attr ); pthread_sigmask( SIG_SETMASK, &sigset, NULL );
if (id) id->UniqueThread = ULongToHandle(tid);