From 03d799897007ab8743c9679cfd6a3e1f7baf602e Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 15 Aug 2003 03:55:06 +0000 Subject: [PATCH] Moved __errno_location() handling to pthread.c, and added similar handling for __res_state(). --- dlls/ntdll/sysdeps.c | 97 ---------------------------- include/thread.h | 1 - scheduler/pthread.c | 147 +++++++++++++++++++++++++++++++++++++------ scheduler/thread.c | 1 - 4 files changed, 129 insertions(+), 117 deletions(-) diff --git a/dlls/ntdll/sysdeps.c b/dlls/ntdll/sysdeps.c index 510064ac552..14dd2b913da 100644 --- a/dlls/ntdll/sysdeps.c +++ b/dlls/ntdll/sysdeps.c @@ -44,9 +44,6 @@ #ifdef HAVE_SCHED_H #include #endif -#ifdef HAVE_VALGRIND_MEMCHECK_H -#include -#endif #ifdef HAVE_NPTL #include @@ -371,100 +368,6 @@ int SYSDEPS_GetUnixTid(void) #endif } - -#ifndef HAVE_NPTL - -/* default errno before threading is initialized */ -static int *default_errno_location(void) -{ - static int static_errno; - return &static_errno; -} - -/* default h_errno before threading is initialized */ -static int *default_h_errno_location(void) -{ - static int static_h_errno; - return &static_h_errno; -} - -/* errno once threading is working */ -static int *thread_errno_location(void) -{ - return &NtCurrentTeb()->thread_errno; -} - -/* h_errno once threading is working */ -static int *thread_h_errno_location(void) -{ - return &NtCurrentTeb()->thread_h_errno; -} - -static int* (*errno_location_ptr)(void) = default_errno_location; -static int* (*h_errno_location_ptr)(void) = default_h_errno_location; - -/*********************************************************************** - * __errno_location/__error/__errno/___errno/__thr_errno - * - * Get the per-thread errno location. - */ -int *__errno_location(void) { return errno_location_ptr(); } /* Linux */ -int *__error(void) { return errno_location_ptr(); } /* FreeBSD */ -int *__errno(void) { return errno_location_ptr(); } /* NetBSD */ -int *___errno(void) { return errno_location_ptr(); } /* Solaris */ -int *__thr_errno(void) { return errno_location_ptr(); } /* UnixWare */ - -/*********************************************************************** - * __h_errno_location - * - * Get the per-thread h_errno location. - */ -int *__h_errno_location(void) -{ - return h_errno_location_ptr(); -} - -#endif /* HAVE_NPTL */ - - -#if defined(__linux__) && defined(__i386__) -static inline void writejump( const char *symbol, void *dest ) -{ - unsigned char *addr = wine_dlsym( RTLD_NEXT, symbol, NULL, 0 ); - - if (!addr) return; - - /* write a relative jump at the function address */ - mprotect((void*)((unsigned int)addr & ~(getpagesize()-1)), 5, PROT_READ|PROT_EXEC|PROT_WRITE); - addr[0] = 0xe9; - *(int *)(addr+1) = (unsigned char *)dest - (addr + 5); - mprotect((void*)((unsigned int)addr & ~(getpagesize()-1)), 5, PROT_READ|PROT_EXEC); - -#ifdef HAVE_VALGRIND_MEMCHECK_H - VALGRIND_DISCARD_TRANSLATIONS( addr, 5 ); -#endif -} -#endif - -/*********************************************************************** - * SYSDEPS_InitErrno - * - * Initialize errno handling. - */ -void SYSDEPS_InitErrno(void) -{ -#ifndef HAVE_NPTL - errno_location_ptr = thread_errno_location; - h_errno_location_ptr = thread_h_errno_location; - -# if defined(__linux__) && defined(__i386__) - writejump( "__errno_location", thread_errno_location ); - writejump( "__h_errno_location", thread_h_errno_location ); -# endif -#endif /* HAVE_NPTL */ -} - - /********************************************************************** * NtCurrentTeb (NTDLL.@) * diff --git a/include/thread.h b/include/thread.h index fb14e7b3827..eb85f7fd820 100644 --- a/include/thread.h +++ b/include/thread.h @@ -147,7 +147,6 @@ extern TEB *THREAD_IdToTEB( DWORD id ); extern int SYSDEPS_SpawnThread( TEB *teb ); extern void SYSDEPS_SetCurThread( TEB *teb ); extern int SYSDEPS_GetUnixTid(void); -extern void SYSDEPS_InitErrno(void); extern void DECLSPEC_NORETURN SYSDEPS_ExitThread( int status ); extern void DECLSPEC_NORETURN SYSDEPS_AbortThread( int status ); extern void DECLSPEC_NORETURN SYSDEPS_SwitchToThreadStack( void (*func)(void *), void *arg ); diff --git a/scheduler/pthread.c b/scheduler/pthread.c index 5a08e26746f..6744931b7d9 100644 --- a/scheduler/pthread.c +++ b/scheduler/pthread.c @@ -21,11 +21,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -struct _pthread_cleanup_buffer; - #include "config.h" #include "wine/port.h" +#ifndef HAVE_NPTL + +struct _pthread_cleanup_buffer; + #define _GNU_SOURCE /* we may need to override some GNU extensions */ #include @@ -36,18 +38,85 @@ struct _pthread_cleanup_buffer; # include #endif #include +#include +#if HAVE_SYS_SOCKET_H +# include +#endif +#ifdef HAVE_SYS_MMAN_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_RESOLV_H +# include +#endif +#ifdef HAVE_VALGRIND_MEMCHECK_H +#include +#endif #include "winbase.h" #include "thread.h" #include "winternl.h" +/* default errno before threading is initialized */ +static int *default_errno_location(void) +{ + static int static_errno; + return &static_errno; +} + +/* default h_errno before threading is initialized */ +static int *default_h_errno_location(void) +{ + static int static_h_errno; + return &static_h_errno; +} + +/* errno once threading is working */ +static int *thread_errno_location(void) +{ + return &NtCurrentTeb()->thread_errno; +} + +/* h_errno once threading is working */ +static int *thread_h_errno_location(void) +{ + return &NtCurrentTeb()->thread_h_errno; +} + +static int* (*errno_location_ptr)(void) = default_errno_location; +static int* (*h_errno_location_ptr)(void) = default_h_errno_location; + +/*********************************************************************** + * __errno_location/__error/__errno/___errno/__thr_errno + * + * Get the per-thread errno location. + */ +int *__errno_location(void) { return errno_location_ptr(); } /* Linux */ +int *__error(void) { return errno_location_ptr(); } /* FreeBSD */ +int *__errno(void) { return errno_location_ptr(); } /* NetBSD */ +int *___errno(void) { return errno_location_ptr(); } /* Solaris */ +int *__thr_errno(void) { return errno_location_ptr(); } /* UnixWare */ + +/*********************************************************************** + * __h_errno_location + * + * Get the per-thread h_errno location. + */ +int *__h_errno_location(void) +{ + return h_errno_location_ptr(); +} + + /* Currently this probably works only for glibc2, * which checks for the presence of double-underscore-prepended * pthread primitives, and use them if available. * If they are not available, the libc defaults to * non-threadsafe operation (not good). */ -#if (defined(__GLIBC__) || defined(__FreeBSD__)) && !defined(HAVE_NPTL) +#if defined(__GLIBC__) || defined(__FreeBSD__) #ifndef __USE_UNIX98 #define __USE_UNIX98 @@ -65,6 +134,8 @@ struct _pthread_cleanup_buffer; asm(".globl " PSTR(alias) "\n" \ "\t.set " PSTR(alias) "," PSTR(orig)) +/* thread descriptor */ + #define FIRST_KEY 0 #define MAX_KEYS 16 /* libc6 doesn't use that many, but... */ #define MAX_TSD 16 @@ -73,13 +144,26 @@ struct fork_block; struct pthread_descr_struct { - char dummy[256]; - const void *key_data[MAX_KEYS]; /* for normal pthread keys */ - const void *tsd_data[MAX_TSD]; /* for libc internal tsd variables */ + char dummy[2048]; + struct __res_state res_state; + const void *key_data[MAX_KEYS]; /* for normal pthread keys */ + const void *tsd_data[MAX_TSD]; /* for libc internal tsd variables */ }; typedef struct pthread_descr_struct *pthread_descr; +static struct pthread_descr_struct initial_descr; + +pthread_descr __pthread_thread_self(void) +{ + struct pthread_descr_struct *descr = NtCurrentTeb()->pthread_data; + if (!descr) return &initial_descr; + return descr; +} +strong_alias(__pthread_thread_self, pthread_thread_self); + +/* pthread functions redirection */ + struct pthread_functions { pid_t (*ptr_pthread_fork) (struct fork_block *); @@ -127,7 +211,6 @@ struct pthread_functions }; static struct pthread_functions wine_pthread_functions; -static struct pthread_descr_struct initial_descr; static int init_done; static pid_t (*libc_fork)(void); @@ -143,6 +226,36 @@ void PTHREAD_init_done(void) if (!libc_sigaction) libc_sigaction = dlsym( RTLD_NEXT, "sigaction" ); } +struct __res_state *__res_state(void) +{ + pthread_descr descr = __pthread_thread_self(); + return &descr->res_state; +} + +static inline void writejump( const char *symbol, void *dest ) +{ +#if defined(__GLIBC__) && defined(__i386__) + unsigned char *addr = dlsym( RTLD_NEXT, symbol ); + + if (!addr) return; + + /* write a relative jump at the function address */ + mprotect((void*)((unsigned int)addr & ~(getpagesize()-1)), 5, PROT_READ|PROT_EXEC|PROT_WRITE); + addr[0] = 0xe9; + *(int *)(addr+1) = (unsigned char *)dest - (addr + 5); + mprotect((void*)((unsigned int)addr & ~(getpagesize()-1)), 5, PROT_READ|PROT_EXEC); + +# ifdef HAVE_VALGRIND_MEMCHECK_H + VALGRIND_DISCARD_TRANSLATIONS( addr, 5 ); +# endif +#endif /* __GLIBC__ && __i386__ */ +} + +/*********************************************************************** + * PTHREAD_init_thread + * + * Initialization for a newly created thread. + */ void PTHREAD_init_thread(void) { static int first = 1; @@ -151,9 +264,14 @@ void PTHREAD_init_thread(void) { first = 0; NtCurrentTeb()->pthread_data = &initial_descr; + errno_location_ptr = thread_errno_location; + h_errno_location_ptr = thread_h_errno_location; libc_uselocale = dlsym( RTLD_NEXT, "uselocale" ); libc_pthread_init = dlsym( RTLD_NEXT, "__libc_pthread_init" ); if (libc_pthread_init) libc_multiple_threads = libc_pthread_init( &wine_pthread_functions ); + writejump( "__errno_location", thread_errno_location ); + writejump( "__h_errno_location", thread_h_errno_location ); + writejump( "__res_state", __res_state ); } else { @@ -200,14 +318,6 @@ void __pthread_initialize(void) { } -pthread_descr __pthread_thread_self(void) -{ - struct pthread_descr_struct *descr = NtCurrentTeb()->pthread_data; - if (!descr) return &initial_descr; - return descr; -} -strong_alias(__pthread_thread_self, pthread_thread_self); - struct pthread_thread_init { void* (*start_routine)(void*); void* arg; @@ -556,7 +666,6 @@ static void ** __attribute__((const)) pthread_internal_tsd_address( int key ) return (void **)&descr->tsd_data[key]; } - /***** "EXCEPTION" FRAMES *****/ /* not implemented right now */ @@ -850,10 +959,12 @@ static struct pthread_functions wine_pthread_functions = NULL /* ptr_pthread_raise */ }; -#else /* __GLIBC__ || __FREEBSD__ */ +#endif /* __GLIBC__ || __FREEBSD__ */ + +#else /* HAVE_NPTL */ void PTHREAD_init_done(void) { } -#endif /* __GLIBC__ || __FREEBSD__ */ +#endif /* HAVE_NPTL */ diff --git a/scheduler/thread.c b/scheduler/thread.c index f2d44ce5744..700006a0d6c 100644 --- a/scheduler/thread.c +++ b/scheduler/thread.c @@ -213,7 +213,6 @@ void THREAD_Init(void) assert( initial_teb.teb_sel ); initial_teb.Peb = (PEB *)¤t_process; /* FIXME */ SYSDEPS_SetCurThread( &initial_teb ); - SYSDEPS_InitErrno(); } }