Fixed a couple of race conditions in the wine_pthread routines at
thread startup and exit.

diff --git a/dlls/kernel/thread.c b/dlls/kernel/thread.c
index 3c5bbd9..0cbddd2 100644
--- a/dlls/kernel/thread.c
+++ b/dlls/kernel/thread.c
@@ -115,6 +115,22 @@
 
 
 /***********************************************************************
+ *           cleanup_teb
+ *
+ * Cleanup the TEB structure; might be called from a different thread.
+ */
+static void cleanup_teb( struct wine_pthread_thread_info *info )
+{
+    TEB *teb = (TEB *)info->teb_base;
+
+    close( teb->wait_fd[0] );
+    close( teb->wait_fd[1] );
+    close( teb->reply_fd );
+    close( teb->request_fd );
+}
+
+
+/***********************************************************************
  *           CreateThread   (KERNEL32.@)
  */
 HANDLE WINAPI CreateThread( SECURITY_ATTRIBUTES *sa, SIZE_T stack,
@@ -213,6 +229,7 @@
         info.stack_base  = NtCurrentTeb()->DeallocationStack;
         info.teb_base    = NtCurrentTeb();
         info.teb_sel     = wine_get_fs();
+        info.cleanup     = cleanup_teb;
         info.exit_status = code;
 
         size = 0;
@@ -234,11 +251,6 @@
         sigaddset( &block_set, SIGTERM );
         sigprocmask( SIG_BLOCK, &block_set, NULL );
 
-        close( NtCurrentTeb()->wait_fd[0] );
-        close( NtCurrentTeb()->wait_fd[1] );
-        close( NtCurrentTeb()->reply_fd );
-        close( NtCurrentTeb()->request_fd );
-
         wine_pthread_exit_thread( &info );
     }
 }
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index 8a0fcca..1251fd3 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -129,6 +129,7 @@
     thread_info.teb_base   = teb;
     thread_info.teb_size   = size;
     thread_info.teb_sel    = teb->teb_sel;
+    wine_pthread_init_current_teb( &thread_info );
     wine_pthread_init_thread( &thread_info );
 
     debug_info.str_pos = debug_info.strings;
@@ -171,9 +172,10 @@
     debug_info.out_pos = debug_info.output;
     teb->debug_info = &debug_info;
 
-    wine_pthread_init_thread( info );
+    wine_pthread_init_current_teb( info );
     SIGNAL_Init();
     server_init_thread( info->pid, info->tid, func );
+    wine_pthread_init_thread( info );
 
     /* allocate a memory view for the stack */
     size = info->stack_size;
diff --git a/include/wine/pthread.h b/include/wine/pthread.h
index 26aa78a..f94794f 100644
--- a/include/wine/pthread.h
+++ b/include/wine/pthread.h
@@ -94,12 +94,14 @@
     int            pid;         /* Unix process id */
     int            tid;         /* Unix thread id */
     void         (*entry)( struct wine_pthread_thread_info *info );  /* thread entry point */
+    void         (*cleanup)( struct wine_pthread_thread_info *info );  /* thread cleanup function */
     int            exit_status; /* thread exit status when calling wine_pthread_exit_thread */
 };
 
 extern void wine_pthread_init_process( const struct wine_pthread_functions *functions );
 extern void wine_pthread_init_thread( struct wine_pthread_thread_info *info );
 extern int wine_pthread_create_thread( struct wine_pthread_thread_info *info );
+extern void wine_pthread_init_current_teb( struct wine_pthread_thread_info *info );
 extern void *wine_pthread_get_current_teb(void);
 extern void DECLSPEC_NORETURN wine_pthread_exit_thread( struct wine_pthread_thread_info *info );
 extern void DECLSPEC_NORETURN wine_pthread_abort_thread( int status );
diff --git a/libs/wine/port.c b/libs/wine/port.c
index 6ba5537..35595c5 100644
--- a/libs/wine/port.c
+++ b/libs/wine/port.c
@@ -67,6 +67,13 @@
 }
 
 /***********************************************************************
+ *           wine_pthread_init_current_teb
+ */
+void wine_pthread_init_current_teb( struct wine_pthread_thread_info *info )
+{
+}
+
+/***********************************************************************
  *           wine_pthread_get_current_teb
  */
 void *wine_pthread_get_current_teb(void)
diff --git a/libs/wine/wine.def b/libs/wine/wine.def
index 439ac0f..bee9bc9 100644
--- a/libs/wine/wine.def
+++ b/libs/wine/wine.def
@@ -59,6 +59,7 @@
     wine_pthread_abort_thread
     wine_pthread_create_thread
     wine_pthread_exit_thread
+    wine_pthread_init_current_teb
     wine_pthread_init_process
     wine_pthread_init_thread
     wine_set_fs
diff --git a/loader/kthread.c b/loader/kthread.c
index 7255f6b..436f059 100644
--- a/loader/kthread.c
+++ b/loader/kthread.c
@@ -189,6 +189,7 @@
 {
     /* copy the info structure since it is on the stack we will free */
     struct wine_pthread_thread_info info = *(struct wine_pthread_thread_info *)ptr;
+    if (info.cleanup) info.cleanup( &info );
     wine_ldt_free_fs( info.teb_sel );
     munmap( info.stack_base, info.stack_size );
     munmap( info.teb_base, info.teb_size );
@@ -220,34 +221,6 @@
 {
     struct pthread_descr_struct *descr;
 
-#ifdef __i386__
-    /* On the i386, the current thread is in the %fs register */
-    LDT_ENTRY fs_entry;
-
-    wine_ldt_set_base( &fs_entry, info->teb_base );
-    wine_ldt_set_limit( &fs_entry, info->teb_size - 1 );
-    wine_ldt_set_flags( &fs_entry, WINE_LDT_FLAGS_DATA|WINE_LDT_FLAGS_32BIT );
-    wine_ldt_init_fs( info->teb_sel, &fs_entry );
-#elif defined(__powerpc__)
-    /* On PowerPC, the current TEB is in the gpr13 register */
-# ifdef __APPLE__
-    __asm__ __volatile__("mr r13, %0" : : "r" (info->teb_base));
-# else
-    __asm__ __volatile__("mr 2, %0" : : "r" (info->teb_base));
-# endif
-#elif defined(HAVE__LWP_CREATE)
-    /* On non-i386 Solaris, we use the LWP private pointer */
-    _lwp_setprivate( info->teb_base );
-#endif
-
-    /* set pid and tid */
-    info->pid = getpid();
-#ifdef HAVE__LWP_SELF
-    info->tid = _lwp_self();
-#else
-    info->tid = -1;
-#endif
-
     if (funcs.ptr_set_thread_data)
     {
         descr = calloc( 1, sizeof(*descr) );
@@ -319,6 +292,43 @@
 
 
 /***********************************************************************
+ *           wine_pthread_init_current_teb
+ *
+ * Set the current TEB for a new thread.
+ */
+void wine_pthread_init_current_teb( struct wine_pthread_thread_info *info )
+{
+#ifdef __i386__
+    /* On the i386, the current thread is in the %fs register */
+    LDT_ENTRY fs_entry;
+
+    wine_ldt_set_base( &fs_entry, info->teb_base );
+    wine_ldt_set_limit( &fs_entry, info->teb_size - 1 );
+    wine_ldt_set_flags( &fs_entry, WINE_LDT_FLAGS_DATA|WINE_LDT_FLAGS_32BIT );
+    wine_ldt_init_fs( info->teb_sel, &fs_entry );
+#elif defined(__powerpc__)
+    /* On PowerPC, the current TEB is in the gpr13 register */
+# ifdef __APPLE__
+    __asm__ __volatile__("mr r13, %0" : : "r" (info->teb_base));
+# else
+    __asm__ __volatile__("mr 2, %0" : : "r" (info->teb_base));
+# endif
+#elif defined(HAVE__LWP_CREATE)
+    /* On non-i386 Solaris, we use the LWP private pointer */
+    _lwp_setprivate( info->teb_base );
+#endif
+
+    /* set pid and tid */
+    info->pid = getpid();
+#ifdef HAVE__LWP_SELF
+    info->tid = _lwp_self();
+#else
+    info->tid = -1;
+#endif
+}
+
+
+/***********************************************************************
  *           wine_pthread_get_current_teb
  */
 void *wine_pthread_get_current_teb(void)
diff --git a/loader/pthread.c b/loader/pthread.c
index 835786d..e8469c2 100644
--- a/loader/pthread.c
+++ b/loader/pthread.c
@@ -62,20 +62,6 @@
  */
 void wine_pthread_init_thread( struct wine_pthread_thread_info *info )
 {
-#ifdef __i386__
-    /* On the i386, the current thread is in the %fs register */
-    LDT_ENTRY fs_entry;
-
-    wine_ldt_set_base( &fs_entry, info->teb_base );
-    wine_ldt_set_limit( &fs_entry, info->teb_size - 1 );
-    wine_ldt_set_flags( &fs_entry, WINE_LDT_FLAGS_DATA|WINE_LDT_FLAGS_32BIT );
-    wine_ldt_init_fs( info->teb_sel, &fs_entry );
-#else
-    if (!funcs.ptr_set_thread_data)  /* first thread */
-        pthread_key_create( &teb_key, NULL );
-    pthread_setspecific( teb_key, info->teb_base );
-#endif
-
     /* retrieve the stack info (except for main thread) */
     if (funcs.ptr_set_thread_data)
     {
@@ -91,10 +77,6 @@
         info->stack_base = stack_top - info->stack_size;
 #endif
     }
-
-    /* set pid and tid */
-    info->pid = getpid();
-    info->tid = gettid();
 }
 
 
@@ -116,6 +98,33 @@
 
 
 /***********************************************************************
+ *           wine_pthread_init_current_teb
+ *
+ * Set the current TEB for a new thread.
+ */
+void wine_pthread_init_current_teb( struct wine_pthread_thread_info *info )
+{
+#ifdef __i386__
+    /* On the i386, the current thread is in the %fs register */
+    LDT_ENTRY fs_entry;
+
+    wine_ldt_set_base( &fs_entry, info->teb_base );
+    wine_ldt_set_limit( &fs_entry, info->teb_size - 1 );
+    wine_ldt_set_flags( &fs_entry, WINE_LDT_FLAGS_DATA|WINE_LDT_FLAGS_32BIT );
+    wine_ldt_init_fs( info->teb_sel, &fs_entry );
+#else
+    if (!funcs.ptr_set_thread_data)  /* first thread */
+        pthread_key_create( &teb_key, NULL );
+    pthread_setspecific( teb_key, info->teb_base );
+#endif
+
+    /* set pid and tid */
+    info->pid = getpid();
+    info->tid = gettid();
+}
+
+
+/***********************************************************************
  *           wine_pthread_get_current_teb
  */
 void *wine_pthread_get_current_teb(void)
@@ -153,6 +162,7 @@
     if ((free_info = interlocked_xchg_ptr( (void **)&previous_info, cleanup_info )) != NULL)
     {
         pthread_join( free_info->self, &ptr );
+        if (free_info->thread_info.cleanup) free_info->thread_info.cleanup( &free_info->thread_info );
         wine_ldt_free_fs( free_info->thread_info.teb_sel );
         munmap( free_info->thread_info.teb_base, free_info->thread_info.teb_size );
     }