From 6281d82e8701ceb9a825a28486f15cb75a1eb0fd Mon Sep 17 00:00:00 2001
From: Alexandre Julliard <julliard@winehq.org>
Date: Tue, 25 Nov 2003 03:42:05 +0000
Subject: [PATCH] Store the thread entry point in the startup info passed to
 the new thread instead of the TEB.

---
 dlls/ntdll/ntdll_misc.h |  2 +-
 dlls/ntdll/server.c     |  4 ++--
 dlls/ntdll/thread.c     | 38 ++++++++++++++++++++++++--------------
 include/thread.h        |  4 +---
 4 files changed, 28 insertions(+), 20 deletions(-)

diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index fb33cc0a382..6e012d156e5 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -51,7 +51,7 @@ extern void thread_init(void);
 
 /* server support */
 extern void server_init_process(void);
-extern void server_init_thread( int unix_pid, int unix_tid );
+extern void server_init_thread( int unix_pid, int unix_tid, void *entry_point );
 extern void DECLSPEC_NORETURN server_protocol_error( const char *err, ... );
 extern void DECLSPEC_NORETURN server_protocol_perror( const char *err );
 extern void DECLSPEC_NORETURN server_abort_thread( int status );
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
index 2226819e959..527011a9d58 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -654,7 +654,7 @@ void server_init_process(void)
  *
  * Send an init thread request. Return 0 if OK.
  */
-void server_init_thread( int unix_pid, int unix_tid )
+void server_init_thread( int unix_pid, int unix_tid, void *entry_point )
 {
     TEB *teb = NtCurrentTeb();
     int version, ret;
@@ -691,7 +691,7 @@ void server_init_thread( int unix_pid, int unix_tid )
         req->unix_pid    = unix_pid;
         req->unix_tid    = unix_tid;
         req->teb         = teb;
-        req->entry       = teb->entry_point;
+        req->entry       = entry_point;
         req->reply_fd    = reply_pipe[1];
         req->wait_fd     = teb->wait_fd[1];
         ret = wine_server_call( req );
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index 196b0f47476..c029f70f29d 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -37,6 +37,14 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(thread);
 
+/* info passed to a starting thread */
+struct startup_info
+{
+    struct wine_pthread_thread_info pthread_info;
+    PRTL_THREAD_START_ROUTINE       entry_point;
+    void                           *entry_arg;
+};
+
 static PEB peb;
 static PEB_LDR_DATA ldr;
 static RTL_USER_PROCESS_PARAMETERS params;  /* default parameters if no parent */
@@ -128,7 +136,7 @@ void thread_init(void)
 
     /* setup the server connection */
     server_init_process();
-    server_init_thread( thread_info.pid, thread_info.tid );
+    server_init_thread( thread_info.pid, thread_info.tid, NULL );
 
     /* create a memory view for the TEB */
     NtAllocateVirtualMemory( GetCurrentProcess(), &addr, teb, &size,
@@ -151,7 +159,9 @@ void thread_init(void)
 static void start_thread( struct wine_pthread_thread_info *info )
 {
     TEB *teb = info->teb_base;
-    LPTHREAD_START_ROUTINE func = (LPTHREAD_START_ROUTINE)teb->entry_point;
+    struct startup_info *startup_info = (struct startup_info *)info;
+    PRTL_THREAD_START_ROUTINE func = startup_info->entry_point;
+    void *arg = startup_info->entry_arg;
     struct debug_info debug_info;
     ULONG size;
 
@@ -161,7 +171,7 @@ static void start_thread( struct wine_pthread_thread_info *info )
 
     wine_pthread_init_thread( info );
     SIGNAL_Init();
-    server_init_thread( info->pid, info->tid );
+    server_init_thread( info->pid, info->tid, func );
 
     /* allocate a memory view for the stack */
     size = info->stack_size;
@@ -181,7 +191,7 @@ static void start_thread( struct wine_pthread_thread_info *info )
     InsertHeadList( &tls_links, &teb->TlsLinks );
     RtlReleasePebLock();
 
-    NtTerminateThread( GetCurrentThread(), func( NtCurrentTeb()->entry_arg ) );
+    func( arg );
 }
 
 
@@ -194,7 +204,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
                                      PRTL_THREAD_START_ROUTINE start, void *param,
                                      HANDLE *handle_ptr, CLIENT_ID *id )
 {
-    struct wine_pthread_thread_info *info = NULL;
+    struct startup_info *info = NULL;
     HANDLE handle = 0;
     TEB *teb = NULL;
     DWORD tid = 0;
@@ -242,14 +252,12 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
     teb->reply_fd    = -1;
     teb->wait_fd[0]  = -1;
     teb->wait_fd[1]  = -1;
-    teb->entry_point = start;
-    teb->entry_arg   = param;
     teb->htask16     = NtCurrentTeb()->htask16;
 
-    NtAllocateVirtualMemory( GetCurrentProcess(), &info->teb_base, teb, &size,
+    NtAllocateVirtualMemory( GetCurrentProcess(), &info->pthread_info.teb_base, teb, &size,
                              MEM_SYSTEM, PAGE_EXECUTE_READWRITE );
-    info->teb_size = size;
-    info->teb_sel  = teb->teb_sel;
+    info->pthread_info.teb_size = size;
+    info->pthread_info.teb_sel  = teb->teb_sel;
 
     if (!stack_reserve || !stack_commit)
     {
@@ -261,11 +269,13 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
     stack_reserve = (stack_reserve + 0xffff) & ~0xffff;  /* round to 64K boundary */
     if (stack_reserve < 1024 * 1024) stack_reserve = 1024 * 1024;  /* Xlib needs a large stack */
 
-    info->stack_base = NULL;
-    info->stack_size = stack_reserve;
-    info->entry      = start_thread;
+    info->pthread_info.stack_base = NULL;
+    info->pthread_info.stack_size = stack_reserve;
+    info->pthread_info.entry      = start_thread;
+    info->entry_point             = start;
+    info->entry_arg               = param;
 
-    if (wine_pthread_create_thread( info ) == -1)
+    if (wine_pthread_create_thread( &info->pthread_info ) == -1)
     {
         status = STATUS_NO_MEMORY;
         goto error;
diff --git a/include/thread.h b/include/thread.h
index f0caf18984f..cdc3b6d1fd5 100644
--- a/include/thread.h
+++ b/include/thread.h
@@ -99,9 +99,7 @@ typedef struct _TEB
     DWORD        unknown4[7];    /* d-n 18c Unknown */
     void        *create_data;    /* d-n 1a8 Pointer to creation structure */
     DWORD        suspend_count;  /* d-n 1ac SuspendThread() counter */
-    void        *entry_point;    /* --3 1b0 Thread entry point (was: unknown) */
-    void        *entry_arg;      /* --3 1b4 Entry point arg (was: unknown) */
-    DWORD        unknown5[4];    /* --n 1b8 Unknown */
+    DWORD        unknown5[6];    /* --n 1b0 Unknown */
     DWORD        sys_count[4];   /* --3 1c8 Syslevel mutex entry counters */
     struct tagSYSLEVEL *sys_mutex[4];   /* --3 1d8 Syslevel mutex pointers */
     DWORD        unknown6[5];    /* --n 1e8 Unknown */
-- 
GitLab