Commit a4d1826c authored by Alexandre Julliard's avatar Alexandre Julliard

Better fix for the thread exit race on pthreads.

parent d9e53caa
...@@ -91,6 +91,7 @@ int wine_pthread_create_thread( struct wine_pthread_thread_info *info ) ...@@ -91,6 +91,7 @@ int wine_pthread_create_thread( struct wine_pthread_thread_info *info )
pthread_attr_init( &attr ); pthread_attr_init( &attr );
pthread_attr_setstacksize( &attr, info->stack_size ); pthread_attr_setstacksize( &attr, info->stack_size );
pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );
if (pthread_create( &id, &attr, (void * (*)(void *))info->entry, info )) ret = -1; if (pthread_create( &id, &attr, (void * (*)(void *))info->entry, info )) ret = -1;
pthread_attr_destroy( &attr ); pthread_attr_destroy( &attr );
return ret; return ret;
...@@ -144,27 +145,8 @@ void *wine_pthread_get_current_teb(void) ...@@ -144,27 +145,8 @@ void *wine_pthread_get_current_teb(void)
*/ */
void wine_pthread_exit_thread( struct wine_pthread_thread_info *info ) void wine_pthread_exit_thread( struct wine_pthread_thread_info *info )
{ {
struct cleanup_info wine_ldt_free_fs( info->teb_sel );
{ munmap( info->teb_base, info->teb_size );
pthread_t self;
struct wine_pthread_thread_info thread_info;
};
static struct cleanup_info *previous_info;
struct cleanup_info *cleanup_info, *free_info;
void *ptr;
/* store it at the end of the TEB structure */
cleanup_info = (struct cleanup_info *)((char *)info->teb_base + info->teb_size) - 1;
cleanup_info->self = pthread_self();
cleanup_info->thread_info = *info;
if ((free_info = interlocked_xchg_ptr( (void **)&previous_info, cleanup_info )) != NULL)
{
pthread_join( free_info->self, &ptr );
wine_ldt_free_fs( free_info->thread_info.teb_sel );
munmap( free_info->thread_info.teb_base, free_info->thread_info.teb_size );
}
pthread_exit( (void *)info->exit_status ); pthread_exit( (void *)info->exit_status );
} }
...@@ -174,7 +156,6 @@ void wine_pthread_exit_thread( struct wine_pthread_thread_info *info ) ...@@ -174,7 +156,6 @@ void wine_pthread_exit_thread( struct wine_pthread_thread_info *info )
*/ */
void wine_pthread_abort_thread( int status ) void wine_pthread_abort_thread( int status )
{ {
pthread_detach( pthread_self() ); /* no one will be joining with us */
pthread_exit( (void *)status ); pthread_exit( (void *)status );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment