From f016752b45123c5b29c48902a55ca4de980d6152 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Sun, 21 Mar 1999 19:26:25 +0000 Subject: [PATCH] Changed process initialisation to use the new server requests. Started to move the process init to the right context, not finished yet. --- include/thread.h | 16 ++-- loader/module.c | 9 --- scheduler/client.c | 69 +++++++--------- scheduler/process.c | 189 +++++++++++++++++++++++++++++++++++++------- scheduler/sysdeps.c | 10 ++- scheduler/thread.c | 101 ++++++++++------------- 6 files changed, 245 insertions(+), 149 deletions(-) diff --git a/include/thread.h b/include/thread.h index 94c9e2ac832..7bb63a08b24 100644 --- a/include/thread.h +++ b/include/thread.h @@ -96,10 +96,11 @@ typedef struct _THDB CRITICAL_SECTION *sys_mutex[4];/* 1e8 Syslevel mutex pointers */ DWORD unknown6[2]; /* 1f8 Unknown */ /* The following are Wine-specific fields */ - int socket; /* 200 Socket for server communication */ - unsigned int seq; /* Server sequence number */ - void *server_tid; /* Server id for this thread */ - struct _THDB *next; /* Global thread list */ + int socket; /* Socket for server communication */ + unsigned int seq; /* Server sequence number */ + void *server_tid; /* Server id for this thread */ + void (*startup)(void); /* Thread startup routine */ + struct _THDB *next; /* Global thread list */ } THDB; /* The pseudo handle value returned by GetCurrentThread */ @@ -115,16 +116,13 @@ extern THDB *pCurrentThread; /* scheduler/thread.c */ -extern THDB *THREAD_CreateInitialThread( struct _PDB *pdb ); +extern THDB *THREAD_CreateInitialThread( struct _PDB *pdb, int server_fd ); extern THDB *THREAD_Create( struct _PDB *pdb, DWORD flags, DWORD stack_size, BOOL alloc_stack16, - LPSECURITY_ATTRIBUTES tsa, LPSECURITY_ATTRIBUTES psa, - int *server_thandle, int *server_phandle, - LPTHREAD_START_ROUTINE start_addr, LPVOID param ); + LPSECURITY_ATTRIBUTES sa, int *server_handle ); extern THDB *THREAD_Current(void); extern BOOL THREAD_IsWin16( THDB *thdb ); extern THDB *THREAD_IdToTHDB( DWORD id ); -extern void THREAD_Start( THDB *thdb ); extern DWORD THREAD_TlsAlloc( THDB *thread ); /* scheduler/sysdeps.c */ diff --git a/loader/module.c b/loader/module.c index c9137b8ed2e..ef9188d87e4 100644 --- a/loader/module.c +++ b/loader/module.c @@ -983,15 +983,6 @@ BOOL WINAPI CreateProcessA( LPCSTR lpApplicationName, LPSTR lpCommandLine, CloseHandle( hFile ); } - - /* Get hTask from process and start the task */ - - if ( retv ) - { - PDB *pdb = PROCESS_IdToPDB( lpProcessInfo->dwProcessId ); - if (pdb) TASK_StartTask( pdb->task ); - } - return retv; } diff --git a/scheduler/client.c b/scheduler/client.c index 54ce0d845d6..82b556dc8b5 100644 --- a/scheduler/client.c +++ b/scheduler/client.c @@ -272,46 +272,42 @@ unsigned int CLIENT_WaitSimpleReply( void *reply, int len, int *passed_fd ) /*********************************************************************** - * CLIENT_NewThread + * CLIENT_InitServer * - * Send a new thread request. + * Start the server and create the initial socket pair. */ -int CLIENT_NewThread( THDB *thdb, - LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa, - int *thandle, int *phandle ) +int CLIENT_InitServer(void) { - struct new_thread_request request; - struct new_thread_reply reply; int fd[2]; + char buffer[16]; + extern void create_initial_thread( int fd ); if (socketpair( AF_UNIX, SOCK_STREAM, 0, fd ) == -1) { - SetLastError( ERROR_TOO_MANY_OPEN_FILES ); /* FIXME */ - return -1; + perror("socketpair"); + exit(1); } - - request.pid = thdb->process->server_pid; - request.suspend = (thdb->flags & CREATE_SUSPENDED)? TRUE : FALSE; - request.tinherit = (tsa && (tsa->nLength>=sizeof(*tsa)) && tsa->bInheritHandle); - request.pinherit = (psa && (psa->nLength>=sizeof(*psa)) && psa->bInheritHandle); - CLIENT_SendRequest( REQ_NEW_THREAD, fd[1], 1, &request, sizeof(request) ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) goto error; - thdb->server_tid = reply.tid; - thdb->process->server_pid = reply.pid; - if (thdb->socket != -1) close( thdb->socket ); - thdb->socket = fd[0]; - thdb->seq = 0; /* reset the sequence number for the new fd */ - fcntl( fd[0], F_SETFD, 1 ); /* set close on exec flag */ - - if (thandle) *thandle = reply.thandle; - else if (reply.thandle != -1) CloseHandle( reply.thandle ); - if (phandle) *phandle = reply.phandle; - else if (reply.phandle != -1) CloseHandle( reply.phandle ); - return 0; - - error: - close( fd[0] ); - return -1; + switch(fork()) + { + case -1: /* error */ + perror("fork"); + exit(1); + case 0: /* child */ + close( fd[0] ); + sprintf( buffer, "%d", fd[1] ); +/*#define EXEC_SERVER*/ +#ifdef EXEC_SERVER + execlp( "wineserver", "wineserver", buffer, NULL ); + execl( "/usr/local/bin/wineserver", "wineserver", buffer, NULL ); + execl( "./server/wineserver", "wineserver", buffer, NULL ); +#endif + create_initial_thread( fd[1] ); + exit(0); + default: /* parent */ + close( fd[1] ); + break; + } + return fd[0]; } @@ -322,16 +318,9 @@ int CLIENT_NewThread( THDB *thdb, */ int CLIENT_InitThread(void) { - THDB *thdb = THREAD_Current(); struct init_thread_request init; - int len = strlen( thdb->process->env_db->cmd_line ); - init.unix_pid = getpid(); - len = MIN( len, MAX_MSG_LENGTH - sizeof(init) ); - - CLIENT_SendRequest( REQ_INIT_THREAD, -1, 2, - &init, sizeof(init), - thdb->process->env_db->cmd_line, len ); + CLIENT_SendRequest( REQ_INIT_THREAD, -1, 1, &init, sizeof(init) ); return CLIENT_WaitReply( NULL, NULL, 0 ); } diff --git a/scheduler/process.c b/scheduler/process.c index 84f12d63dca..5f7bb342025 100644 --- a/scheduler/process.c +++ b/scheduler/process.c @@ -178,6 +178,55 @@ static BOOL PROCESS_InheritEnvDB( PDB *pdb, LPCSTR cmd_line, LPCSTR env, } +/*********************************************************************** + * PROCESS_CreateEnvDB + * + * Create the env DB for a newly started process. + */ +static BOOL PROCESS_CreateEnvDB(void) +{ + struct init_process_request req; + struct init_process_reply reply; + STARTUPINFOA *startup; + ENVDB *env_db; + PDB *pdb = PROCESS_Current(); + + /* Retrieve startup info from the server */ + + req.dummy = 0; + CLIENT_SendRequest( REQ_INIT_PROCESS, -1, 1, &req, sizeof(req) ); + if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE; + + /* Allocate the env DB */ + + if (!(env_db = HeapAlloc( pdb->heap, HEAP_ZERO_MEMORY, sizeof(ENVDB) ))) + return FALSE; + pdb->env_db = env_db; + InitializeCriticalSection( &env_db->section ); + + /* Allocate and fill the startup info */ + if (!(startup = HeapAlloc( pdb->heap, HEAP_ZERO_MEMORY, sizeof(STARTUPINFOA) ))) + return FALSE; + pdb->env_db->startup_info = startup; + startup->dwFlags = reply.start_flags; + pdb->env_db->hStdin = startup->hStdInput = reply.hstdin; + pdb->env_db->hStdout = startup->hStdOutput = reply.hstdout; + pdb->env_db->hStderr = startup->hStdError = reply.hstderr; + +#if 0 /* FIXME */ + /* Copy the parent environment */ + + if (!ENV_InheritEnvironment( pdb, env )) return FALSE; + + /* Copy the command line */ + + if (!(pdb->env_db->cmd_line = HEAP_strdupA( pdb->heap, 0, cmd_line ))) + return FALSE; +#endif + return TRUE; +} + + /*********************************************************************** * PROCESS_FreePDB * @@ -191,7 +240,6 @@ void PROCESS_FreePDB( PDB *pdb ) while (*pptr && (*pptr != pdb)) pptr = &(*pptr)->next; if (*pptr) *pptr = pdb->next; if (pdb->heap && (pdb->heap != pdb->system_heap)) HeapDestroy( pdb->heap ); - DeleteCriticalSection( &pdb->crit_section ); HeapFree( SystemHeap, 0, pdb ); } @@ -222,27 +270,16 @@ static PDB *PROCESS_CreatePDB( PDB *parent, BOOL inherit ) } -/*********************************************************************** - * PROCESS_FinishCreatePDB - * - * Second part of CreatePDB - */ -static BOOL PROCESS_FinishCreatePDB( PDB *pdb ) -{ - InitializeCriticalSection( &pdb->crit_section ); - /* Allocate the event */ - if (!(pdb->load_done_evt = CreateEventA( NULL, TRUE, FALSE, NULL ))) - return FALSE; - return TRUE; -} - - /*********************************************************************** * PROCESS_Init */ BOOL PROCESS_Init(void) { THDB *thdb; + int server_fd; + + /* Start the server */ + server_fd = CLIENT_InitServer(); /* Fill the initial process structure */ initial_pdb.exit_code = 0x103; /* STILL_ACTIVE */ @@ -255,8 +292,8 @@ BOOL PROCESS_Init(void) /* Initialize virtual memory management */ if (!VIRTUAL_Init()) return FALSE; - /* Create the initial thread structure */ - if (!(thdb = THREAD_CreateInitialThread( &initial_pdb ))) return FALSE; + /* Create the initial thread structure and socket pair */ + if (!(thdb = THREAD_CreateInitialThread( &initial_pdb, server_fd ))) return FALSE; /* Remember TEB selector of initial process for emergency use */ SYSLEVEL_EmergencyTeb = thdb->teb_sel; @@ -270,15 +307,82 @@ BOOL PROCESS_Init(void) /* Initialize the first thread */ if (CLIENT_InitThread()) return FALSE; - if (!PROCESS_FinishCreatePDB( &initial_pdb )) return FALSE; /* Create the SEGPTR heap */ if (!(SegptrHeap = HeapCreate( HEAP_WINE_SEGPTR, 0, 0 ))) return FALSE; + /* Initialize the first process critical section */ + InitializeCriticalSection( &initial_pdb.crit_section ); + return TRUE; } +/*********************************************************************** + * PROCESS_Start + * + * Startup routine of a new process. Called in the context of the new process. + */ +void PROCESS_Start(void) +{ + DWORD size, commit; + UINT cmdShow = 0; + LPTHREAD_START_ROUTINE entry; + THDB *thdb = THREAD_Current(); + PDB *pdb = thdb->process; + NE_MODULE *pModule = (NE_MODULE *)thdb->entry_arg; /* hack */ + + /* Initialize the critical section */ + + InitializeCriticalSection( &pdb->crit_section ); + + /* Create the heap */ + + size = PE_HEADER(pModule->module32)->OptionalHeader.SizeOfHeapReserve; + commit = PE_HEADER(pModule->module32)->OptionalHeader.SizeOfHeapCommit; + if (!(pdb->heap = HeapCreate( HEAP_GROWABLE, size, commit ))) goto error; + pdb->heap_list = pdb->heap; + + /* Create the environment db */ + + if (!PROCESS_CreateEnvDB()) goto error; + +#if 0 + if (pdb->env_db->startup_info->dwFlags & STARTF_USESHOWWINDOW) + cmdShow = pdb->env_db->startup_info->wShowWindow; + if (!TASK_Create( thdb, pModule, 0, 0, cmdShow )) goto error; +#endif + + /* Map system DLLs into this process (from initial process) */ + /* FIXME: this is a hack */ + pdb->modref_list = PROCESS_Initial()->modref_list; + + /* Create 32-bit MODREF */ + { + OFSTRUCT *ofs = (OFSTRUCT *)((char*)(pModule) + (pModule)->fileinfo); + if (!PE_CreateModule( pModule->module32, ofs, 0, FALSE )) goto error; + } + + /* Initialize thread-local storage */ + + PE_InitTls( thdb ); + + if (PE_HEADER(pModule->module32)->OptionalHeader.Subsystem==IMAGE_SUBSYSTEM_WINDOWS_CUI) + AllocConsole(); + + /* Now call the entry point */ + + MODULE_InitializeDLLs( 0, DLL_PROCESS_ATTACH, (LPVOID)-1 ); + entry = (LPTHREAD_START_ROUTINE)RVA_PTR(pModule->module32, + OptionalHeader.AddressOfEntryPoint); + TRACE(relay, "(entryproc=%p)\n", entry ); + ExitProcess( entry(NULL) ); + + error: + ExitProcess(1); +} + + /*********************************************************************** * PROCESS_Create * @@ -291,7 +395,9 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env, PROCESS_INFORMATION *info ) { DWORD size, commit; - int server_thandle, server_phandle; + int server_thandle; + struct new_process_request req; + struct new_process_reply reply; UINT cmdShow = 0; THDB *thdb = NULL; PDB *parent = PROCESS_Current(); @@ -299,7 +405,33 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env, if (!pdb) return NULL; info->hThread = info->hProcess = INVALID_HANDLE_VALUE; - if (!PROCESS_FinishCreatePDB( pdb )) goto error; + + /* Create the process on the server side */ + + req.inherit = (psa && (psa->nLength >= sizeof(*psa)) && psa->bInheritHandle); + req.inherit_all = inherit; + req.start_flags = startup->dwFlags; + if (startup->dwFlags & STARTF_USESTDHANDLES) + { + req.hstdin = startup->hStdInput; + req.hstdout = startup->hStdOutput; + req.hstderr = startup->hStdError; + } + else + { + req.hstdin = GetStdHandle( STD_INPUT_HANDLE ); + req.hstdout = GetStdHandle( STD_OUTPUT_HANDLE ); + req.hstderr = GetStdHandle( STD_ERROR_HANDLE ); + } + CLIENT_SendRequest( REQ_NEW_PROCESS, -1, 1, &req, sizeof(req) ); + if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) goto error; + pdb->server_pid = reply.pid; + info->hProcess = reply.handle; + info->dwProcessId = (DWORD)pdb->server_pid; + + /* Initialize the critical section */ + + InitializeCriticalSection( &pdb->crit_section ); /* Create the heap */ @@ -327,13 +459,9 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env, size = PE_HEADER(pModule->module32)->OptionalHeader.SizeOfStackReserve; else size = 0; - if (!(thdb = THREAD_Create( pdb, 0L, size, hInstance == 0, - tsa, psa, &server_thandle, &server_phandle, - NULL, NULL ))) + if (!(thdb = THREAD_Create( pdb, 0L, size, hInstance == 0, tsa, &server_thandle ))) goto error; info->hThread = server_thandle; - info->hProcess = server_phandle; - info->dwProcessId = (DWORD)pdb->server_pid; info->dwThreadId = (DWORD)thdb->server_tid; /* Duplicate the standard handles */ @@ -362,6 +490,10 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env, pdb->modref_list = PROCESS_Initial()->modref_list; + /* Start the task */ + + TASK_StartTask( pdb->task ); + return pdb; error: @@ -381,12 +513,13 @@ void WINAPI ExitProcess( DWORD status ) TDB *pTask = (TDB *)GlobalLock16( pdb->task ); if ( pTask ) pTask->nEvents++; + MODULE_InitializeDLLs( 0, DLL_PROCESS_DETACH, NULL ); + if ( pTask && pTask->thdb != THREAD_Current() ) - ExitThread( status ); + TerminateProcess( GetCurrentProcess(), status ); /* FIXME: should kill all running threads of this process */ pdb->exit_code = status; - FreeConsole(); __RESTORE_ES; /* Necessary for Pietrek's showseh example program */ TASK_KillCurrentTask( status ); diff --git a/scheduler/sysdeps.c b/scheduler/sysdeps.c index ac41e8a1c77..b634901706f 100644 --- a/scheduler/sysdeps.c +++ b/scheduler/sysdeps.c @@ -80,8 +80,14 @@ int *__h_errno_location() */ static void SYSDEPS_StartThread( THDB *thdb ) { - SET_FS( thdb->teb_sel ); - THREAD_Start( thdb ); + struct init_thread_request init; + + SET_CUR_THREAD( thdb ); + init.unix_pid = getpid(); + CLIENT_SendRequest( REQ_INIT_THREAD, -1, 1, &init, sizeof(init) ); + CLIENT_WaitReply( NULL, NULL, 0 ); + thdb->startup(); + _exit(0); /* should never get here */ } #endif /* USE_THREADS */ diff --git a/scheduler/thread.c b/scheduler/thread.c index bf784043647..f08cde6f5dc 100644 --- a/scheduler/thread.c +++ b/scheduler/thread.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -94,8 +95,7 @@ THDB *THREAD_IdToTHDB( DWORD id ) * Initialization of a newly created THDB. */ static BOOL THREAD_InitTHDB( THDB *thdb, DWORD stack_size, BOOL alloc_stack16, - LPSECURITY_ATTRIBUTES tsa, LPSECURITY_ATTRIBUTES psa, - int *server_thandle, int *server_phandle ) + LPSECURITY_ATTRIBUTES sa ) { DWORD old_prot; @@ -136,11 +136,6 @@ static BOOL THREAD_InitTHDB( THDB *thdb, DWORD stack_size, BOOL alloc_stack16, 0x10000 - sizeof(STACK16FRAME) ); } - /* Create the thread socket */ - - if (CLIENT_NewThread( thdb, tsa, psa, server_thandle, server_phandle )) - goto error; - /* Create the thread event */ if (!(thdb->event = CreateEventA( NULL, FALSE, FALSE, NULL ))) goto error; @@ -148,7 +143,6 @@ static BOOL THREAD_InitTHDB( THDB *thdb, DWORD stack_size, BOOL alloc_stack16, return TRUE; error: - if (thdb->socket != -1) close( thdb->socket ); if (thdb->event) CloseHandle( thdb->event ); if (thdb->teb.stack_sel) SELECTOR_FreeBlock( thdb->teb.stack_sel, 1 ); if (thdb->stack_base) VirtualFree( thdb->stack_base, 0, MEM_RELEASE ); @@ -189,51 +183,16 @@ void THREAD_FreeTHDB( THDB *thdb ) * * Create the initial thread. */ -THDB *THREAD_CreateInitialThread( PDB *pdb ) +THDB *THREAD_CreateInitialThread( PDB *pdb, int server_fd ) { - int fd[2]; - char buffer[16]; - extern void server_init( int fd ); - extern void select_loop(void); - initial_thdb.process = pdb; initial_thdb.teb.except = (void *)-1; initial_thdb.teb.self = &initial_thdb.teb; - initial_thdb.teb.flags = (pdb->flags & PDB32_WIN16_PROC)? 0 : TEBF_WIN32; + initial_thdb.teb.flags = TEBF_WIN32; initial_thdb.teb.tls_ptr = initial_thdb.tls_array; initial_thdb.teb.process = pdb; initial_thdb.exit_code = 0x103; /* STILL_ACTIVE */ - initial_thdb.socket = -1; - - /* Start the server */ - - if (socketpair( AF_UNIX, SOCK_STREAM, 0, fd ) == -1) - { - perror("socketpair"); - exit(1); - } - switch(fork()) - { - case -1: /* error */ - perror("fork"); - exit(1); - case 0: /* child */ - close( fd[0] ); - sprintf( buffer, "%d", fd[1] ); -/*#define EXEC_SERVER*/ -#ifdef EXEC_SERVER - execlp( "wineserver", "wineserver", buffer, NULL ); - execl( "/usr/local/bin/wineserver", "wineserver", buffer, NULL ); - execl( "./server/wineserver", "wineserver", buffer, NULL ); -#endif - server_init( fd[1] ); - select_loop(); - exit(0); - default: /* parent */ - initial_thdb.socket = fd[0]; - close( fd[1] ); - break; - } + initial_thdb.socket = server_fd; /* Allocate the TEB selector (%fs register) */ @@ -248,8 +207,7 @@ THDB *THREAD_CreateInitialThread( PDB *pdb ) /* Now proceed with normal initialization */ - if (!THREAD_InitTHDB( &initial_thdb, 0, TRUE, - NULL, NULL, NULL, NULL )) return NULL; + if (!THREAD_InitTHDB( &initial_thdb, 0, TRUE, NULL )) return NULL; return &initial_thdb; } @@ -258,10 +216,12 @@ THDB *THREAD_CreateInitialThread( PDB *pdb ) * THREAD_Create */ THDB *THREAD_Create( PDB *pdb, DWORD flags, DWORD stack_size, BOOL alloc_stack16, - LPSECURITY_ATTRIBUTES tsa, LPSECURITY_ATTRIBUTES psa, - int *server_thandle, int *server_phandle, - LPTHREAD_START_ROUTINE start_addr, LPVOID param ) + LPSECURITY_ATTRIBUTES sa, int *server_handle ) { + struct new_thread_request request; + struct new_thread_reply reply = { NULL, -1 }; + int fd[2]; + THDB *thdb = HeapAlloc( SystemHeap, HEAP_ZERO_MEMORY, sizeof(THDB) ); if (!thdb) return NULL; thdb->process = pdb; @@ -273,8 +233,6 @@ THDB *THREAD_Create( PDB *pdb, DWORD flags, DWORD stack_size, BOOL alloc_stack16 thdb->teb.process = pdb; thdb->exit_code = 0x103; /* STILL_ACTIVE */ thdb->flags = flags; - thdb->entry_point = start_addr; - thdb->entry_arg = param; thdb->socket = -1; /* Allocate the TEB selector (%fs register) */ @@ -283,19 +241,39 @@ THDB *THREAD_Create( PDB *pdb, DWORD flags, DWORD stack_size, BOOL alloc_stack16 TRUE, FALSE ); if (!thdb->teb_sel) goto error; + /* Create the socket pair for server communication */ + + if (socketpair( AF_UNIX, SOCK_STREAM, 0, fd ) == -1) + { + SetLastError( ERROR_TOO_MANY_OPEN_FILES ); /* FIXME */ + goto error; + } + thdb->socket = fd[0]; + fcntl( fd[0], F_SETFD, 1 ); /* set close on exec flag */ + + /* Create the thread on the server side */ + + request.pid = thdb->process->server_pid; + request.suspend = ((thdb->flags & CREATE_SUSPENDED) != 0); + request.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); + CLIENT_SendRequest( REQ_NEW_THREAD, fd[1], 1, &request, sizeof(request) ); + if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) goto error; + thdb->server_tid = reply.tid; + *server_handle = reply.handle; + /* Do the rest of the initialization */ - if (!THREAD_InitTHDB( thdb, stack_size, alloc_stack16, - tsa, psa, server_thandle, server_phandle )) - goto error; + if (!THREAD_InitTHDB( thdb, stack_size, alloc_stack16, sa )) goto error; thdb->next = THREAD_First; THREAD_First = thdb; PE_InitTls( thdb ); return thdb; error: + if (reply.handle != -1) CloseHandle( reply.handle ); if (thdb->teb_sel) SELECTOR_FreeBlock( thdb->teb_sel, 1 ); HeapFree( SystemHeap, 0, thdb ); + if (thdb->socket != -1) close( thdb->socket ); return NULL; } @@ -305,11 +283,10 @@ error: * * Start execution of a newly created thread. Does not return. */ -void THREAD_Start( THDB *thdb ) +static void THREAD_Start(void) { + THDB *thdb = THREAD_Current(); LPTHREAD_START_ROUTINE func = (LPTHREAD_START_ROUTINE)thdb->entry_point; - assert( THREAD_Current() == thdb ); - CLIENT_InitThread(); MODULE_InitializeDLLs( 0, DLL_THREAD_ATTACH, NULL ); ExitThread( func( thdb->entry_arg ) ); } @@ -323,9 +300,11 @@ HANDLE WINAPI CreateThread( SECURITY_ATTRIBUTES *sa, DWORD stack, DWORD flags, LPDWORD id ) { int handle = -1; - THDB *thread = THREAD_Create( PROCESS_Current(), flags, stack, - TRUE, sa, NULL, &handle, NULL, start, param ); + THDB *thread = THREAD_Create( PROCESS_Current(), flags, stack, TRUE, sa, &handle ); if (!thread) return INVALID_HANDLE_VALUE; + thread->entry_point = start; + thread->entry_arg = param; + thread->startup = THREAD_Start; if (SYSDEPS_SpawnThread( thread ) == -1) { CloseHandle( handle );