ntdll: Add a helper for platform-specific threading initialization.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2020-04-28 13:17:07 +02:00
parent 69f068bfb1
commit ffb7c595c6
7 changed files with 60 additions and 42 deletions

View File

@ -77,6 +77,7 @@ extern LPCSTR debugstr_us( const UNICODE_STRING *str ) DECLSPEC_HIDDEN;
extern LPCSTR debugstr_ObjectAttributes(const OBJECT_ATTRIBUTES *oa) DECLSPEC_HIDDEN;
/* init routines */
extern void signal_init_threading(void) DECLSPEC_HIDDEN;
extern NTSTATUS signal_alloc_thread( TEB **teb ) DECLSPEC_HIDDEN;
extern void signal_free_thread( TEB *teb ) DECLSPEC_HIDDEN;
extern void signal_init_thread( TEB *teb ) DECLSPEC_HIDDEN;

View File

@ -952,6 +952,15 @@ int CDECL __wine_set_signal_handler(unsigned int sig, wine_signal_handler wsh)
}
/**********************************************************************
* signal_init_threading
*/
void signal_init_threading(void)
{
pthread_key_create( &teb_key, NULL );
}
/**********************************************************************
* signal_alloc_thread
*/
@ -997,14 +1006,6 @@ void signal_free_thread( TEB *teb )
*/
void signal_init_thread( TEB *teb )
{
static BOOL init_done;
if (!init_done)
{
pthread_key_create( &teb_key, NULL );
init_done = TRUE;
}
#if defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_8A__)
/* Win32/ARM applications expect the TEB pointer to be in the TPIDRURW register. */
__asm__ __volatile__( "mcr p15, 0, %0, c13, c0, 2" : : "r" (teb) );

View File

@ -1250,6 +1250,15 @@ int CDECL __wine_set_signal_handler(unsigned int sig, wine_signal_handler wsh)
}
/**********************************************************************
* signal_init_threading
*/
void signal_init_threading(void)
{
pthread_key_create( &teb_key, NULL );
}
/**********************************************************************
* signal_alloc_thread
*/
@ -1286,15 +1295,8 @@ void signal_free_thread( TEB *teb )
*/
void signal_init_thread( TEB *teb )
{
static BOOL init_done;
stack_t ss;
if (!init_done)
{
pthread_key_create( &teb_key, NULL );
init_done = TRUE;
}
ss.ss_sp = (char *)teb + teb_size;
ss.ss_size = signal_stack_size;
ss.ss_flags = 0;

View File

@ -2438,25 +2438,6 @@ static void ldt_set_entry( WORD sel, LDT_ENTRY entry )
LDT_FLAGS_ALLOCATED);
}
static void ldt_init(void)
{
#ifdef __linux__
/* the preloader may have allocated it already */
gdt_fs_sel = get_fs();
if (!gdt_fs_sel || !is_gdt_sel( gdt_fs_sel ))
{
struct modify_ldt_s ldt_info = { -1 };
ldt_info.seg_32bit = 1;
ldt_info.usable = 1;
if (set_thread_area( &ldt_info ) >= 0) gdt_fs_sel = (ldt_info.entry_number << 3) | 3;
else gdt_fs_sel = 0;
}
#elif defined(__FreeBSD__) || defined (__FreeBSD_kernel__)
gdt_fs_sel = GSEL( GUFS_SEL, SEL_UPL );
#endif
}
WORD ldt_alloc_fs( TEB *teb, int first_thread )
{
LDT_ENTRY entry;
@ -2583,6 +2564,29 @@ NTSTATUS WINAPI NtSetLdtEntries( ULONG sel1, LDT_ENTRY entry1, ULONG sel2, LDT_E
}
/**********************************************************************
* signal_init_threading
*/
void signal_init_threading(void)
{
#ifdef __linux__
/* the preloader may have allocated it already */
gdt_fs_sel = get_fs();
if (!gdt_fs_sel || !is_gdt_sel( gdt_fs_sel ))
{
struct modify_ldt_s ldt_info = { -1 };
ldt_info.seg_32bit = 1;
ldt_info.usable = 1;
if (set_thread_area( &ldt_info ) >= 0) gdt_fs_sel = (ldt_info.entry_number << 3) | 3;
else gdt_fs_sel = 0;
}
#elif defined(__FreeBSD__) || defined (__FreeBSD_kernel__)
gdt_fs_sel = GSEL( GUFS_SEL, SEL_UPL );
#endif
}
/**********************************************************************
* signal_alloc_thread
*/
@ -2603,7 +2607,6 @@ NTSTATUS signal_alloc_thread( TEB **teb )
while ((1u << sigstack_alignment) < min_size) sigstack_alignment++;
signal_stack_mask = (1 << sigstack_alignment) - 1;
signal_stack_size = (1 << sigstack_alignment) - teb_size;
ldt_init();
}
size = signal_stack_mask + 1;

View File

@ -1013,6 +1013,15 @@ int CDECL __wine_set_signal_handler(unsigned int sig, wine_signal_handler wsh)
}
/**********************************************************************
* signal_init_threading
*/
void signal_init_threading(void)
{
pthread_key_create( &teb_key, NULL );
}
/**********************************************************************
* signal_alloc_thread
*/
@ -1058,13 +1067,6 @@ void signal_free_thread( TEB *teb )
*/
void signal_init_thread( TEB *teb )
{
static BOOL init_done;
if (!init_done)
{
pthread_key_create( &teb_key, NULL );
init_done = TRUE;
}
pthread_setspecific( teb_key, teb );
}

View File

@ -3107,6 +3107,14 @@ int CDECL __wine_set_signal_handler(unsigned int sig, wine_signal_handler wsh)
}
/**********************************************************************
* signal_init_threading
*/
void signal_init_threading(void)
{
}
/**********************************************************************
* signal_alloc_thread
*/

View File

@ -284,6 +284,7 @@ TEB *thread_init(void)
/* allocate and initialize the initial TEB */
signal_init_threading();
signal_alloc_thread( &teb );
teb->Peb = peb;
teb->Tib.StackBase = (void *)~0UL;