/* * @implemented */ VOID WINAPI ExitProcess(UINT uExitCode) { // CSR_API_MESSAGE CsrRequest; // ULONG Request; NTSTATUS Status; /* kill sibling threads ... we want to be alone at this point */ NtTerminateProcess(NULL, 0); /* unload all dll's */ LdrShutdownProcess(); /* notify csrss of process termination */ // Request = TERMINATE_PROCESS; // Status = CsrClientCallServer(&CsrRequest, // NULL, // MAKE_CSR_API(Request, CSR_NATIVE), // sizeof(CSR_API_MESSAGE)); // if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrRequest.Status)) // { // DPRINT("Failed to tell csrss about terminating process\n"); // } NtTerminateProcess(NtCurrentProcess (), uExitCode); /* should never get here */ ASSERT(0); while(1); }
/*********************************************************************** * exit_thread */ void exit_thread( int status ) { static void *prev_teb; shmlocal_t *shmlocal; sigset_t sigset; TEB *teb; if (status) /* send the exit code to the server (0 is already the default) */ { SERVER_START_REQ( terminate_thread ) { req->handle = wine_server_obj_handle( GetCurrentThread() ); req->exit_code = status; wine_server_call( req ); } SERVER_END_REQ; } if (interlocked_xchg_add( &nb_threads, 0 ) <= 1) { LdrShutdownProcess(); exit( status ); } LdrShutdownThread(); RtlFreeThreadActivationContextStack(); shmlocal = interlocked_xchg_ptr( &NtCurrentTeb()->Reserved5[2], NULL ); if (shmlocal) NtUnmapViewOfSection( NtCurrentProcess(), shmlocal ); pthread_sigmask( SIG_BLOCK, &server_block_set, NULL ); if ((teb = interlocked_xchg_ptr( &prev_teb, NtCurrentTeb() ))) { struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SpareBytes1; if (thread_data->pthread_id) { pthread_join( thread_data->pthread_id, NULL ); signal_free_thread( teb ); } } sigemptyset( &sigset ); sigaddset( &sigset, SIGQUIT ); pthread_sigmask( SIG_BLOCK, &sigset, NULL ); if (interlocked_xchg_add( &nb_threads, -1 ) <= 1) _exit( status ); 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_exit( UIntToPtr(status) ); }
/*********************************************************************** * exit_thread */ void exit_thread( int status ) { static void *prev_teb; TEB *teb; if (status) /* send the exit code to the server (0 is already the default) */ { SERVER_START_REQ( terminate_thread ) { req->handle = wine_server_obj_handle( GetCurrentThread() ); req->exit_code = status; wine_server_call( req ); } SERVER_END_REQ; } if (interlocked_xchg_add( &nb_threads, -1 ) <= 1) { LdrShutdownProcess(); #ifdef CONFIG_UNIFIED_KERNEL server_kill_thread( status ); #endif exit( status ); } LdrShutdownThread(); pthread_sigmask( SIG_BLOCK, &server_block_set, NULL ); if ((teb = interlocked_xchg_ptr( &prev_teb, NtCurrentTeb() ))) { struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SpareBytes1; if (thread_data->pthread_id) { pthread_join( thread_data->pthread_id, NULL ); signal_free_thread( teb ); } } 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 ); #ifdef CONFIG_UNIFIED_KERNEL server_kill_thread( status ); #endif pthread_exit( UIntToPtr(status) ); }
/*********************************************************************** * exit_thread */ void exit_thread( int status ) { static void *prev_teb; TEB *teb; if (status) /* send the exit code to the server (0 is already the default) */ { SERVER_START_REQ( terminate_thread ) { req->handle = wine_server_obj_handle( GetCurrentThread() ); req->exit_code = status; wine_server_call( req ); } SERVER_END_REQ; } if (interlocked_xchg_add( &nb_threads, -1 ) <= 1) { LdrShutdownProcess(); exit( status ); } LdrShutdownThread(); RtlAcquirePebLock(); RemoveEntryList( &NtCurrentTeb()->TlsLinks ); RtlReleasePebLock(); RtlFreeHeap( GetProcessHeap(), 0, NtCurrentTeb()->FlsSlots ); RtlFreeHeap( GetProcessHeap(), 0, NtCurrentTeb()->TlsExpansionSlots ); pthread_sigmask( SIG_BLOCK, &server_block_set, NULL ); if ((teb = interlocked_xchg_ptr( &prev_teb, NtCurrentTeb() ))) { struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SpareBytes1; if (thread_data->pthread_id) { pthread_join( thread_data->pthread_id, NULL ); signal_free_thread( teb ); } } 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_exit( UIntToPtr(status) ); }