Properly free thread stacks on NPTL systems.
This commit is contained in:
parent
9ebf12c36d
commit
8669193d11
|
@ -99,6 +99,10 @@ void SYSDEPS_SetCurThread( TEB *teb )
|
|||
/* On non-i386 Solaris, we use the LWP private pointer */
|
||||
_lwp_setprivate( teb );
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NPTL
|
||||
teb->pthread_data = (void *)pthread_self();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -160,7 +164,6 @@ int SYSDEPS_SpawnThread( TEB *teb )
|
|||
pthread_attr_t attr;
|
||||
|
||||
pthread_attr_init( &attr );
|
||||
pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );
|
||||
pthread_attr_setstack( &attr, teb->stack_base, (char *)teb->stack_top - (char *)teb->stack_base );
|
||||
if (pthread_create( &id, &attr, (void * (*)(void *))SYSDEPS_StartThread, teb )) return -1;
|
||||
return 0;
|
||||
|
@ -277,9 +280,29 @@ void SYSDEPS_SwitchToThreadStack( void (*func)(void *), void *arg )
|
|||
void SYSDEPS_ExitThread( int status )
|
||||
{
|
||||
TEB *teb = NtCurrentTeb();
|
||||
DWORD size = 0;
|
||||
|
||||
#ifdef HAVE_NPTL
|
||||
static TEB *teb_to_free;
|
||||
TEB *free_teb;
|
||||
|
||||
if ((free_teb = interlocked_xchg_ptr( (void **)&teb_to_free, teb )) != NULL)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
TRACE("freeing prev teb %p stack %p fs %04x\n",
|
||||
free_teb, free_teb->stack_base, free_teb->teb_sel );
|
||||
|
||||
pthread_join( (pthread_t)free_teb->pthread_data, &ptr );
|
||||
wine_ldt_free_fs( free_teb->teb_sel );
|
||||
ptr = free_teb->stack_base;
|
||||
NtFreeVirtualMemory( GetCurrentProcess(), &ptr, &size, MEM_RELEASE );
|
||||
}
|
||||
SIGNAL_Block();
|
||||
SYSDEPS_AbortThread( status );
|
||||
#else
|
||||
struct thread_cleanup_info info;
|
||||
MEMORY_BASIC_INFORMATION meminfo;
|
||||
DWORD size = 0;
|
||||
|
||||
NtQueryVirtualMemory( GetCurrentProcess(), teb->stack_top, MemoryBasicInformation,
|
||||
&meminfo, sizeof(meminfo), NULL );
|
||||
|
@ -288,17 +311,13 @@ void SYSDEPS_ExitThread( int status )
|
|||
info.status = status;
|
||||
|
||||
SIGNAL_Block();
|
||||
|
||||
#ifdef HAVE_NPTL
|
||||
SYSDEPS_AbortThread( status );
|
||||
#else
|
||||
SIGNAL_Reset();
|
||||
size = 0;
|
||||
NtFreeVirtualMemory( GetCurrentProcess(), &teb->stack_base, &size, MEM_RELEASE | MEM_SYSTEM );
|
||||
close( teb->wait_fd[0] );
|
||||
close( teb->wait_fd[1] );
|
||||
close( teb->reply_fd );
|
||||
close( teb->request_fd );
|
||||
SIGNAL_Reset();
|
||||
teb->stack_low = get_temp_stack();
|
||||
teb->stack_top = (char *) teb->stack_low + TEMP_STACK_SIZE;
|
||||
SYSDEPS_SwitchToThreadStack( cleanup_thread, &info );
|
||||
|
|
Loading…
Reference in New Issue