ntdll: Moved the TEB allocation routines to the platform-specific files.
This commit is contained in:
parent
d4fc2fd746
commit
d4f1fffacc
|
@ -59,9 +59,10 @@ extern NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handl
|
||||||
const LARGE_INTEGER *timeout, HANDLE signal_object );
|
const LARGE_INTEGER *timeout, HANDLE signal_object );
|
||||||
|
|
||||||
/* init routines */
|
/* init routines */
|
||||||
|
extern NTSTATUS signal_alloc_thread( TEB **teb );
|
||||||
|
extern void signal_free_thread( TEB *teb );
|
||||||
extern void signal_init_thread( TEB *teb );
|
extern void signal_init_thread( TEB *teb );
|
||||||
extern void signal_init_process(void);
|
extern void signal_init_process(void);
|
||||||
extern size_t get_signal_stack_total_size(void);
|
|
||||||
extern void version_init( const WCHAR *appname );
|
extern void version_init( const WCHAR *appname );
|
||||||
extern void debug_init(void);
|
extern void debug_init(void);
|
||||||
extern HANDLE thread_init(void);
|
extern HANDLE thread_init(void);
|
||||||
|
|
|
@ -1995,26 +1995,6 @@ static void usr1_handler( int signal, siginfo_t *siginfo, void *sigcontext )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
|
||||||
* get_signal_stack_total_size
|
|
||||||
*
|
|
||||||
* Retrieve the size to allocate for the signal stack, including the TEB at the bottom.
|
|
||||||
* Must be a power of two.
|
|
||||||
*/
|
|
||||||
size_t get_signal_stack_total_size(void)
|
|
||||||
{
|
|
||||||
if (!signal_stack_size)
|
|
||||||
{
|
|
||||||
size_t size = 8192, min_size = teb_size + max( MINSIGSTKSZ, 8192 );
|
|
||||||
/* find the first power of two not smaller than min_size */
|
|
||||||
while (size < min_size) size *= 2;
|
|
||||||
signal_stack_mask = size - 1;
|
|
||||||
signal_stack_size = size - teb_size;
|
|
||||||
}
|
|
||||||
return signal_stack_size + teb_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* __wine_set_signal_handler (NTDLL.@)
|
* __wine_set_signal_handler (NTDLL.@)
|
||||||
*/
|
*/
|
||||||
|
@ -2027,6 +2007,65 @@ int CDECL __wine_set_signal_handler(unsigned int sig, wine_signal_handler wsh)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* signal_alloc_thread
|
||||||
|
*/
|
||||||
|
NTSTATUS signal_alloc_thread( TEB **teb )
|
||||||
|
{
|
||||||
|
static size_t sigstack_zero_bits;
|
||||||
|
struct ntdll_thread_data *thread_data;
|
||||||
|
SIZE_T size;
|
||||||
|
void *addr = NULL;
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
if (!sigstack_zero_bits)
|
||||||
|
{
|
||||||
|
size_t min_size = teb_size + max( MINSIGSTKSZ, 8192 );
|
||||||
|
/* find the first power of two not smaller than min_size */
|
||||||
|
sigstack_zero_bits = 12;
|
||||||
|
while ((1u << sigstack_zero_bits) < min_size) sigstack_zero_bits++;
|
||||||
|
signal_stack_mask = (1 << sigstack_zero_bits) - 1;
|
||||||
|
signal_stack_size = (1 << sigstack_zero_bits) - teb_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = signal_stack_mask + 1;
|
||||||
|
if (!(status = NtAllocateVirtualMemory( NtCurrentProcess(), &addr, sigstack_zero_bits,
|
||||||
|
&size, MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE )))
|
||||||
|
{
|
||||||
|
*teb = addr;
|
||||||
|
(*teb)->Tib.Self = &(*teb)->Tib;
|
||||||
|
(*teb)->Tib.ExceptionList = (void *)~0UL;
|
||||||
|
thread_data = (struct ntdll_thread_data *)(*teb)->SystemReserved2;
|
||||||
|
if (!(thread_data->fs = wine_ldt_alloc_fs()))
|
||||||
|
{
|
||||||
|
size = 0;
|
||||||
|
NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE );
|
||||||
|
status = STATUS_TOO_MANY_THREADS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* signal_free_thread
|
||||||
|
*/
|
||||||
|
void signal_free_thread( TEB *teb )
|
||||||
|
{
|
||||||
|
SIZE_T size;
|
||||||
|
struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SystemReserved2;
|
||||||
|
|
||||||
|
if (thread_data) wine_ldt_free_fs( thread_data->fs );
|
||||||
|
if (teb->DeallocationStack)
|
||||||
|
{
|
||||||
|
size = 0;
|
||||||
|
NtFreeVirtualMemory( GetCurrentProcess(), &teb->DeallocationStack, &size, MEM_RELEASE );
|
||||||
|
}
|
||||||
|
size = 0;
|
||||||
|
NtFreeVirtualMemory( NtCurrentProcess(), (void **)&teb, &size, MEM_RELEASE );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* signal_init_thread
|
* signal_init_thread
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -965,19 +965,6 @@ static void usr1_handler( int signal, siginfo_t *siginfo, void *sigcontext )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
|
||||||
* get_signal_stack_total_size
|
|
||||||
*
|
|
||||||
* Retrieve the size to allocate for the signal stack, including the TEB at the bottom.
|
|
||||||
* Must be a power of two.
|
|
||||||
*/
|
|
||||||
size_t get_signal_stack_total_size(void)
|
|
||||||
{
|
|
||||||
assert( sizeof(TEB) <= getpagesize() );
|
|
||||||
return getpagesize(); /* this is just for the TEB, we don't need a signal stack */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* __wine_set_signal_handler (NTDLL.@)
|
* __wine_set_signal_handler (NTDLL.@)
|
||||||
*/
|
*/
|
||||||
|
@ -990,6 +977,52 @@ int CDECL __wine_set_signal_handler(unsigned int sig, wine_signal_handler wsh)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* signal_alloc_thread
|
||||||
|
*/
|
||||||
|
NTSTATUS signal_alloc_thread( TEB **teb )
|
||||||
|
{
|
||||||
|
static size_t sigstack_zero_bits;
|
||||||
|
SIZE_T size;
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
if (!sigstack_zero_bits)
|
||||||
|
{
|
||||||
|
size_t min_size = getpagesize(); /* this is just for the TEB, we don't use a signal stack yet */
|
||||||
|
/* find the first power of two not smaller than min_size */
|
||||||
|
while ((1u << sigstack_zero_bits) < min_size) sigstack_zero_bits++;
|
||||||
|
assert( sizeof(TEB) <= min_size );
|
||||||
|
}
|
||||||
|
|
||||||
|
size = 1 << sigstack_zero_bits;
|
||||||
|
*teb = NULL;
|
||||||
|
if (!(status = NtAllocateVirtualMemory( NtCurrentProcess(), (void **)teb, sigstack_zero_bits,
|
||||||
|
&size, MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE )))
|
||||||
|
{
|
||||||
|
(*teb)->Tib.Self = &(*teb)->Tib;
|
||||||
|
(*teb)->Tib.ExceptionList = (void *)~0UL;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* signal_free_thread
|
||||||
|
*/
|
||||||
|
void signal_free_thread( TEB *teb )
|
||||||
|
{
|
||||||
|
SIZE_T size;
|
||||||
|
|
||||||
|
if (teb->DeallocationStack)
|
||||||
|
{
|
||||||
|
size = 0;
|
||||||
|
NtFreeVirtualMemory( GetCurrentProcess(), &teb->DeallocationStack, &size, MEM_RELEASE );
|
||||||
|
}
|
||||||
|
size = 0;
|
||||||
|
NtFreeVirtualMemory( NtCurrentProcess(), (void **)&teb, &size, MEM_RELEASE );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* signal_init_thread
|
* signal_init_thread
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -700,19 +700,6 @@ static void usr1_handler( int signal, struct siginfo *info, void *ucontext )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
|
||||||
* get_signal_stack_total_size
|
|
||||||
*
|
|
||||||
* Retrieve the size to allocate for the signal stack, including the TEB at the bottom.
|
|
||||||
* Must be a power of two.
|
|
||||||
*/
|
|
||||||
size_t get_signal_stack_total_size(void)
|
|
||||||
{
|
|
||||||
assert( sizeof(TEB) <= getpagesize() );
|
|
||||||
return getpagesize(); /* this is just for the TEB, we don't need a signal stack */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* __wine_set_signal_handler (NTDLL.@)
|
* __wine_set_signal_handler (NTDLL.@)
|
||||||
*/
|
*/
|
||||||
|
@ -725,6 +712,52 @@ int CDECL __wine_set_signal_handler(unsigned int sig, wine_signal_handler wsh)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* signal_alloc_thread
|
||||||
|
*/
|
||||||
|
NTSTATUS signal_alloc_thread( TEB **teb )
|
||||||
|
{
|
||||||
|
static size_t sigstack_zero_bits;
|
||||||
|
SIZE_T size;
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
if (!sigstack_zero_bits)
|
||||||
|
{
|
||||||
|
size_t min_size = getpagesize(); /* this is just for the TEB, we don't use a signal stack yet */
|
||||||
|
/* find the first power of two not smaller than min_size */
|
||||||
|
while ((1u << sigstack_zero_bits) < min_size) sigstack_zero_bits++;
|
||||||
|
assert( sizeof(TEB) <= min_size );
|
||||||
|
}
|
||||||
|
|
||||||
|
size = 1 << sigstack_zero_bits;
|
||||||
|
*teb = NULL;
|
||||||
|
if (!(status = NtAllocateVirtualMemory( NtCurrentProcess(), (void **)teb, sigstack_zero_bits,
|
||||||
|
&size, MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE )))
|
||||||
|
{
|
||||||
|
(*teb)->Tib.Self = &(*teb)->Tib;
|
||||||
|
(*teb)->Tib.ExceptionList = (void *)~0UL;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* signal_free_thread
|
||||||
|
*/
|
||||||
|
void signal_free_thread( TEB *teb )
|
||||||
|
{
|
||||||
|
SIZE_T size;
|
||||||
|
|
||||||
|
if (teb->DeallocationStack)
|
||||||
|
{
|
||||||
|
size = 0;
|
||||||
|
NtFreeVirtualMemory( GetCurrentProcess(), &teb->DeallocationStack, &size, MEM_RELEASE );
|
||||||
|
}
|
||||||
|
size = 0;
|
||||||
|
NtFreeVirtualMemory( NtCurrentProcess(), (void **)&teb, &size, MEM_RELEASE );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* signal_init_thread
|
* signal_init_thread
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2191,26 +2191,6 @@ static void usr1_handler( int signal, siginfo_t *siginfo, void *ucontext )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
|
||||||
* get_signal_stack_total_size
|
|
||||||
*
|
|
||||||
* Retrieve the size to allocate for the signal stack, including the TEB at the bottom.
|
|
||||||
* Must be a power of two.
|
|
||||||
*/
|
|
||||||
size_t get_signal_stack_total_size(void)
|
|
||||||
{
|
|
||||||
assert( sizeof(TEB) <= teb_size );
|
|
||||||
if (!signal_stack_size)
|
|
||||||
{
|
|
||||||
size_t size = 8192, min_size = teb_size + max( MINSIGSTKSZ, 8192 );
|
|
||||||
/* find the first power of two not smaller than min_size */
|
|
||||||
while (size < min_size) size *= 2;
|
|
||||||
signal_stack_size = size - teb_size;
|
|
||||||
}
|
|
||||||
return signal_stack_size + teb_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* __wine_set_signal_handler (NTDLL.@)
|
* __wine_set_signal_handler (NTDLL.@)
|
||||||
*/
|
*/
|
||||||
|
@ -2223,6 +2203,54 @@ int CDECL __wine_set_signal_handler(unsigned int sig, wine_signal_handler wsh)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* signal_alloc_thread
|
||||||
|
*/
|
||||||
|
NTSTATUS signal_alloc_thread( TEB **teb )
|
||||||
|
{
|
||||||
|
static size_t sigstack_zero_bits;
|
||||||
|
SIZE_T size;
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
if (!sigstack_zero_bits)
|
||||||
|
{
|
||||||
|
size_t min_size = teb_size + max( MINSIGSTKSZ, 8192 );
|
||||||
|
/* find the first power of two not smaller than min_size */
|
||||||
|
sigstack_zero_bits = 12;
|
||||||
|
while ((1u << sigstack_zero_bits) < min_size) sigstack_zero_bits++;
|
||||||
|
signal_stack_size = (1 << sigstack_zero_bits) - teb_size;
|
||||||
|
assert( sizeof(TEB) <= teb_size );
|
||||||
|
}
|
||||||
|
|
||||||
|
size = 1 << sigstack_zero_bits;
|
||||||
|
*teb = NULL;
|
||||||
|
if (!(status = NtAllocateVirtualMemory( NtCurrentProcess(), (void **)teb, sigstack_zero_bits,
|
||||||
|
&size, MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE )))
|
||||||
|
{
|
||||||
|
(*teb)->Tib.Self = &(*teb)->Tib;
|
||||||
|
(*teb)->Tib.ExceptionList = (void *)~0UL;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* signal_free_thread
|
||||||
|
*/
|
||||||
|
void signal_free_thread( TEB *teb )
|
||||||
|
{
|
||||||
|
SIZE_T size;
|
||||||
|
|
||||||
|
if (teb->DeallocationStack)
|
||||||
|
{
|
||||||
|
size = 0;
|
||||||
|
NtFreeVirtualMemory( GetCurrentProcess(), &teb->DeallocationStack, &size, MEM_RELEASE );
|
||||||
|
}
|
||||||
|
size = 0;
|
||||||
|
NtFreeVirtualMemory( NtCurrentProcess(), (void **)&teb, &size, MEM_RELEASE );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* signal_init_thread
|
* signal_init_thread
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -64,8 +64,6 @@ static RTL_BITMAP tls_bitmap;
|
||||||
static RTL_BITMAP tls_expansion_bitmap;
|
static RTL_BITMAP tls_expansion_bitmap;
|
||||||
static RTL_BITMAP fls_bitmap;
|
static RTL_BITMAP fls_bitmap;
|
||||||
static LIST_ENTRY tls_links;
|
static LIST_ENTRY tls_links;
|
||||||
static size_t sigstack_total_size;
|
|
||||||
static ULONG sigstack_zero_bits;
|
|
||||||
static int nb_threads = 1;
|
static int nb_threads = 1;
|
||||||
|
|
||||||
static RTL_CRITICAL_SECTION ldt_section;
|
static RTL_CRITICAL_SECTION ldt_section;
|
||||||
|
@ -102,29 +100,6 @@ static void ldt_unlock(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* init_teb
|
|
||||||
*/
|
|
||||||
static inline NTSTATUS init_teb( TEB *teb )
|
|
||||||
{
|
|
||||||
struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SystemReserved2;
|
|
||||||
|
|
||||||
teb->Tib.ExceptionList = (void *)~0UL;
|
|
||||||
teb->Tib.StackBase = (void *)~0UL;
|
|
||||||
teb->Tib.Self = &teb->Tib;
|
|
||||||
teb->StaticUnicodeString.Buffer = teb->StaticUnicodeBuffer;
|
|
||||||
teb->StaticUnicodeString.MaximumLength = sizeof(teb->StaticUnicodeBuffer);
|
|
||||||
|
|
||||||
if (!(thread_data->fs = wine_ldt_alloc_fs())) return STATUS_TOO_MANY_THREADS;
|
|
||||||
thread_data->request_fd = -1;
|
|
||||||
thread_data->reply_fd = -1;
|
|
||||||
thread_data->wait_fd[0] = -1;
|
|
||||||
thread_data->wait_fd[1] = -1;
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* get_unicode_string
|
* get_unicode_string
|
||||||
*
|
*
|
||||||
|
@ -297,19 +272,17 @@ HANDLE thread_init(void)
|
||||||
|
|
||||||
/* allocate and initialize the initial TEB */
|
/* allocate and initialize the initial TEB */
|
||||||
|
|
||||||
sigstack_total_size = get_signal_stack_total_size();
|
signal_alloc_thread( &teb );
|
||||||
while (1U << sigstack_zero_bits < sigstack_total_size) sigstack_zero_bits++;
|
|
||||||
assert( 1U << sigstack_zero_bits == sigstack_total_size ); /* must be a power of 2 */
|
|
||||||
assert( sigstack_total_size >= sizeof(TEB) + sizeof(struct startup_info) );
|
|
||||||
|
|
||||||
addr = NULL;
|
|
||||||
size = sigstack_total_size;
|
|
||||||
NtAllocateVirtualMemory( NtCurrentProcess(), &addr, sigstack_zero_bits,
|
|
||||||
&size, MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE );
|
|
||||||
teb = addr;
|
|
||||||
teb->Peb = peb;
|
teb->Peb = peb;
|
||||||
init_teb( teb );
|
teb->Tib.StackBase = (void *)~0UL;
|
||||||
|
teb->StaticUnicodeString.Buffer = teb->StaticUnicodeBuffer;
|
||||||
|
teb->StaticUnicodeString.MaximumLength = sizeof(teb->StaticUnicodeBuffer);
|
||||||
|
|
||||||
thread_data = (struct ntdll_thread_data *)teb->SystemReserved2;
|
thread_data = (struct ntdll_thread_data *)teb->SystemReserved2;
|
||||||
|
thread_data->request_fd = -1;
|
||||||
|
thread_data->reply_fd = -1;
|
||||||
|
thread_data->wait_fd[0] = -1;
|
||||||
|
thread_data->wait_fd[1] = -1;
|
||||||
thread_data->debug_info = &debug_info;
|
thread_data->debug_info = &debug_info;
|
||||||
InsertHeadList( &tls_links, &teb->TlsLinks );
|
InsertHeadList( &tls_links, &teb->TlsLinks );
|
||||||
|
|
||||||
|
@ -417,14 +390,9 @@ void exit_thread( int status )
|
||||||
if ((teb = interlocked_xchg_ptr( &prev_teb, NtCurrentTeb() )))
|
if ((teb = interlocked_xchg_ptr( &prev_teb, NtCurrentTeb() )))
|
||||||
{
|
{
|
||||||
struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SystemReserved2;
|
struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SystemReserved2;
|
||||||
SIZE_T size;
|
|
||||||
|
|
||||||
pthread_join( thread_data->pthread_id, NULL );
|
pthread_join( thread_data->pthread_id, NULL );
|
||||||
wine_ldt_free_fs( thread_data->fs );
|
signal_free_thread( teb );
|
||||||
size = 0;
|
|
||||||
NtFreeVirtualMemory( GetCurrentProcess(), &teb->DeallocationStack, &size, MEM_RELEASE );
|
|
||||||
size = 0;
|
|
||||||
NtFreeVirtualMemory( GetCurrentProcess(), (void **)&teb, &size, MEM_RELEASE );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
close( ntdll_get_thread_data()->wait_fd[0] );
|
close( ntdll_get_thread_data()->wait_fd[0] );
|
||||||
|
@ -482,16 +450,14 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
|
||||||
sigset_t sigset;
|
sigset_t sigset;
|
||||||
pthread_t pthread_id;
|
pthread_t pthread_id;
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
struct ntdll_thread_data *thread_data = NULL;
|
struct ntdll_thread_data *thread_data;
|
||||||
struct ntdll_thread_regs *thread_regs;
|
struct ntdll_thread_regs *thread_regs;
|
||||||
struct startup_info *info = NULL;
|
struct startup_info *info = NULL;
|
||||||
void *addr = NULL;
|
|
||||||
HANDLE handle = 0;
|
HANDLE handle = 0;
|
||||||
TEB *teb;
|
TEB *teb = NULL;
|
||||||
DWORD tid = 0;
|
DWORD tid = 0;
|
||||||
int request_pipe[2];
|
int request_pipe[2];
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
SIZE_T size;
|
|
||||||
|
|
||||||
if (process != NtCurrentProcess())
|
if (process != NtCurrentProcess())
|
||||||
{
|
{
|
||||||
|
@ -544,26 +510,25 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
|
||||||
|
|
||||||
pthread_sigmask( SIG_BLOCK, &server_block_set, &sigset );
|
pthread_sigmask( SIG_BLOCK, &server_block_set, &sigset );
|
||||||
|
|
||||||
addr = NULL;
|
if ((status = signal_alloc_thread( &teb ))) goto error;
|
||||||
size = sigstack_total_size;
|
|
||||||
if ((status = NtAllocateVirtualMemory( NtCurrentProcess(), &addr, sigstack_zero_bits,
|
|
||||||
&size, MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE )))
|
|
||||||
goto error;
|
|
||||||
teb = addr;
|
|
||||||
teb->Peb = NtCurrentTeb()->Peb;
|
teb->Peb = NtCurrentTeb()->Peb;
|
||||||
|
teb->ClientId.UniqueProcess = ULongToHandle(GetCurrentProcessId());
|
||||||
|
teb->ClientId.UniqueThread = ULongToHandle(tid);
|
||||||
|
teb->StaticUnicodeString.Buffer = teb->StaticUnicodeBuffer;
|
||||||
|
teb->StaticUnicodeString.MaximumLength = sizeof(teb->StaticUnicodeBuffer);
|
||||||
|
|
||||||
info = (struct startup_info *)(teb + 1);
|
info = (struct startup_info *)(teb + 1);
|
||||||
info->teb = teb;
|
info->teb = teb;
|
||||||
info->entry_point = start;
|
info->entry_point = start;
|
||||||
info->entry_arg = param;
|
info->entry_arg = param;
|
||||||
|
|
||||||
if ((status = init_teb( teb ))) goto error;
|
|
||||||
|
|
||||||
teb->ClientId.UniqueProcess = ULongToHandle(GetCurrentProcessId());
|
|
||||||
teb->ClientId.UniqueThread = ULongToHandle(tid);
|
|
||||||
|
|
||||||
thread_data = (struct ntdll_thread_data *)teb->SystemReserved2;
|
thread_data = (struct ntdll_thread_data *)teb->SystemReserved2;
|
||||||
thread_regs = (struct ntdll_thread_regs *)teb->SpareBytes1;
|
thread_regs = (struct ntdll_thread_regs *)teb->SpareBytes1;
|
||||||
thread_data->request_fd = request_pipe[1];
|
thread_data->request_fd = request_pipe[1];
|
||||||
|
thread_data->reply_fd = -1;
|
||||||
|
thread_data->wait_fd[0] = -1;
|
||||||
|
thread_data->wait_fd[1] = -1;
|
||||||
|
|
||||||
/* inherit debug registers from parent thread */
|
/* inherit debug registers from parent thread */
|
||||||
thread_regs->dr0 = ntdll_get_thread_regs()->dr0;
|
thread_regs->dr0 = ntdll_get_thread_regs()->dr0;
|
||||||
|
@ -584,8 +549,6 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
|
||||||
{
|
{
|
||||||
interlocked_xchg_add( &nb_threads, -1 );
|
interlocked_xchg_add( &nb_threads, -1 );
|
||||||
pthread_attr_destroy( &attr );
|
pthread_attr_destroy( &attr );
|
||||||
size = 0;
|
|
||||||
NtFreeVirtualMemory( NtCurrentProcess(), &teb->DeallocationStack, &size, MEM_RELEASE );
|
|
||||||
status = STATUS_NO_MEMORY;
|
status = STATUS_NO_MEMORY;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -599,12 +562,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (thread_data) wine_ldt_free_fs( thread_data->fs );
|
if (teb) signal_free_thread( teb );
|
||||||
if (addr)
|
|
||||||
{
|
|
||||||
size = 0;
|
|
||||||
NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE );
|
|
||||||
}
|
|
||||||
if (handle) NtClose( handle );
|
if (handle) NtClose( handle );
|
||||||
pthread_sigmask( SIG_SETMASK, &sigset, NULL );
|
pthread_sigmask( SIG_SETMASK, &sigset, NULL );
|
||||||
close( request_pipe[1] );
|
close( request_pipe[1] );
|
||||||
|
|
Loading…
Reference in New Issue