ntdll: Stop sharing the thread counter with the Unix library.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
635593a01c
commit
2334f4e645
|
@ -2670,6 +2670,36 @@ static void test_thread_lookup(void)
|
|||
"NtOpenThread returned %#x\n", status);
|
||||
}
|
||||
|
||||
static void test_thread_info(void)
|
||||
{
|
||||
NTSTATUS status;
|
||||
ULONG len, data;
|
||||
|
||||
len = 0xdeadbeef;
|
||||
data = 0xcccccccc;
|
||||
status = pNtQueryInformationThread( GetCurrentThread(), ThreadAmILastThread,
|
||||
&data, sizeof(data), &len );
|
||||
ok( !status, "failed %x\n", status );
|
||||
ok( data == 0 || data == 1, "wrong data %x\n", data );
|
||||
ok( len == sizeof(data), "wrong len %u\n", len );
|
||||
|
||||
len = 0xdeadbeef;
|
||||
data = 0xcccccccc;
|
||||
status = pNtQueryInformationThread( GetCurrentThread(), ThreadAmILastThread,
|
||||
&data, sizeof(data) - 1, &len );
|
||||
ok( status == STATUS_INFO_LENGTH_MISMATCH, "failed %x\n", status );
|
||||
ok( data == 0xcccccccc, "wrong data %x\n", data );
|
||||
ok( len == 0xdeadbeef, "wrong len %u\n", len );
|
||||
|
||||
len = 0xdeadbeef;
|
||||
data = 0xcccccccc;
|
||||
status = pNtQueryInformationThread( GetCurrentThread(), ThreadAmILastThread,
|
||||
&data, sizeof(data) + 1, &len );
|
||||
ok( status == STATUS_INFO_LENGTH_MISMATCH, "failed %x\n", status );
|
||||
ok( data == 0xcccccccc, "wrong data %x\n", data );
|
||||
ok( len == 0xdeadbeef, "wrong len %u\n", len );
|
||||
}
|
||||
|
||||
START_TEST(info)
|
||||
{
|
||||
char **argv;
|
||||
|
@ -2827,4 +2857,5 @@ START_TEST(info)
|
|||
test_query_data_alignment();
|
||||
|
||||
test_thread_lookup();
|
||||
test_thread_info();
|
||||
}
|
||||
|
|
|
@ -45,7 +45,6 @@ static PEB_LDR_DATA ldr;
|
|||
static RTL_BITMAP tls_bitmap;
|
||||
static RTL_BITMAP tls_expansion_bitmap;
|
||||
static RTL_BITMAP fls_bitmap;
|
||||
static int nb_threads = 1;
|
||||
|
||||
struct ldt_copy *__wine_ldt_copy = NULL;
|
||||
|
||||
|
@ -105,7 +104,7 @@ int __cdecl __wine_dbg_output( const char *str )
|
|||
TEB *thread_init( SIZE_T *info_size )
|
||||
{
|
||||
ULONG_PTR val;
|
||||
TEB *teb = unix_funcs->init_threading( &nb_threads, &__wine_ldt_copy, info_size );
|
||||
TEB *teb = unix_funcs->init_threading( &__wine_ldt_copy, info_size );
|
||||
|
||||
peb = teb->Peb;
|
||||
peb->FastPebLock = &peb_lock;
|
||||
|
@ -147,6 +146,8 @@ TEB *thread_init( SIZE_T *info_size )
|
|||
*/
|
||||
void WINAPI RtlExitUserThread( ULONG status )
|
||||
{
|
||||
ULONG last;
|
||||
|
||||
if (status) /* send the exit code to the server (0 is already the default) */
|
||||
{
|
||||
SERVER_START_REQ( terminate_thread )
|
||||
|
@ -158,12 +159,12 @@ void WINAPI RtlExitUserThread( ULONG status )
|
|||
SERVER_END_REQ;
|
||||
}
|
||||
|
||||
if (InterlockedDecrement( &nb_threads ) <= 0)
|
||||
NtQueryInformationThread( GetCurrentThread(), ThreadAmILastThread, &last, sizeof(last), NULL );
|
||||
if (last)
|
||||
{
|
||||
LdrShutdownProcess();
|
||||
unix_funcs->exit_process( status );
|
||||
}
|
||||
|
||||
LdrShutdownThread();
|
||||
RtlFreeThreadActivationContextStack();
|
||||
for (;;) unix_funcs->exit_thread( status );
|
||||
|
|
|
@ -60,7 +60,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(seh);
|
|||
#define PTHREAD_STACK_MIN 16384
|
||||
#endif
|
||||
|
||||
static int *nb_threads;
|
||||
static int nb_threads = 1;
|
||||
|
||||
static inline int get_unix_exit_code( NTSTATUS status )
|
||||
{
|
||||
|
@ -86,7 +86,7 @@ static void pthread_exit_wrapper( int status )
|
|||
/***********************************************************************
|
||||
* init_threading
|
||||
*/
|
||||
TEB * CDECL init_threading( int *nb_threads_ptr, struct ldt_copy **ldt_copy, SIZE_T *size )
|
||||
TEB * CDECL init_threading( struct ldt_copy **ldt_copy, SIZE_T *size )
|
||||
{
|
||||
TEB *teb;
|
||||
BOOL suspend;
|
||||
|
@ -95,7 +95,6 @@ TEB * CDECL init_threading( int *nb_threads_ptr, struct ldt_copy **ldt_copy, SIZ
|
|||
extern struct ldt_copy __wine_ldt_copy;
|
||||
*ldt_copy = &__wine_ldt_copy;
|
||||
#endif
|
||||
nb_threads = nb_threads_ptr;
|
||||
|
||||
teb = virtual_alloc_first_teb();
|
||||
|
||||
|
@ -290,10 +289,10 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT
|
|||
(char *)teb->Tib.StackBase + extra_stack - (char *)teb->DeallocationStack );
|
||||
pthread_attr_setguardsize( &pthread_attr, 0 );
|
||||
pthread_attr_setscope( &pthread_attr, PTHREAD_SCOPE_SYSTEM ); /* force creating a kernel thread */
|
||||
InterlockedIncrement( nb_threads );
|
||||
InterlockedIncrement( &nb_threads );
|
||||
if (pthread_create( &pthread_id, &pthread_attr, (void * (*)(void *))start_thread, teb ))
|
||||
{
|
||||
InterlockedDecrement( nb_threads );
|
||||
InterlockedDecrement( &nb_threads );
|
||||
virtual_free_teb( teb );
|
||||
status = STATUS_NO_MEMORY;
|
||||
}
|
||||
|
@ -319,7 +318,7 @@ done:
|
|||
void abort_thread( int status )
|
||||
{
|
||||
pthread_sigmask( SIG_BLOCK, &server_block_set, NULL );
|
||||
if (InterlockedDecrement( nb_threads ) <= 0) abort_process( status );
|
||||
if (InterlockedDecrement( &nb_threads ) <= 0) abort_process( status );
|
||||
signal_exit_thread( status, pthread_exit_wrapper );
|
||||
}
|
||||
|
||||
|
@ -987,6 +986,7 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class,
|
|||
|
||||
case ThreadAmILastThread:
|
||||
{
|
||||
if (length != sizeof(ULONG)) return STATUS_INFO_LENGTH_MISMATCH;
|
||||
SERVER_START_REQ( get_thread_info )
|
||||
{
|
||||
req->handle = wine_server_obj_handle( handle );
|
||||
|
@ -994,9 +994,9 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class,
|
|||
status = wine_server_call( req );
|
||||
if (status == STATUS_SUCCESS)
|
||||
{
|
||||
BOOLEAN last = reply->last;
|
||||
if (data) memcpy( data, &last, min( length, sizeof(last) ));
|
||||
if (ret_len) *ret_len = min( length, sizeof(last) );
|
||||
ULONG last = reply->last;
|
||||
if (data) memcpy( data, &last, sizeof(last) );
|
||||
if (ret_len) *ret_len = sizeof(last);
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
|
|
@ -117,7 +117,7 @@ extern NTSTATUS CDECL server_handle_to_fd( HANDLE handle, unsigned int access, i
|
|||
unsigned int *options ) DECLSPEC_HIDDEN;
|
||||
extern void CDECL server_release_fd( HANDLE handle, int unix_fd ) DECLSPEC_HIDDEN;
|
||||
extern void CDECL server_init_process_done( void *relay ) DECLSPEC_HIDDEN;
|
||||
extern TEB * CDECL init_threading( int *nb_threads_ptr, struct ldt_copy **ldt_copy, SIZE_T *size ) DECLSPEC_HIDDEN;
|
||||
extern TEB * CDECL init_threading( struct ldt_copy **ldt_copy, SIZE_T *size ) DECLSPEC_HIDDEN;
|
||||
extern void CDECL DECLSPEC_NORETURN exit_thread( int status ) DECLSPEC_HIDDEN;
|
||||
extern void CDECL DECLSPEC_NORETURN exit_process( int status ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS CDECL exec_process( UNICODE_STRING *path, UNICODE_STRING *cmdline, NTSTATUS status ) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -29,7 +29,7 @@ struct msghdr;
|
|||
struct _DISPATCHER_CONTEXT;
|
||||
|
||||
/* increment this when you change the function table */
|
||||
#define NTDLL_UNIXLIB_VERSION 65
|
||||
#define NTDLL_UNIXLIB_VERSION 66
|
||||
|
||||
struct unix_funcs
|
||||
{
|
||||
|
@ -319,7 +319,7 @@ struct unix_funcs
|
|||
void (CDECL *virtual_set_large_address_space)(void);
|
||||
|
||||
/* thread/process functions */
|
||||
TEB * (CDECL *init_threading)( int *nb_threads_ptr, struct ldt_copy **ldt_copy, SIZE_T *size );
|
||||
TEB * (CDECL *init_threading)( struct ldt_copy **ldt_copy, SIZE_T *size );
|
||||
void (CDECL *exit_thread)( int status );
|
||||
void (CDECL *exit_process)( int status );
|
||||
NTSTATUS (CDECL *exec_process)( UNICODE_STRING *path, UNICODE_STRING *cmdline, NTSTATUS status );
|
||||
|
|
Loading…
Reference in New Issue