Commit 598412ed authored by Alexandre Julliard's avatar Alexandre Julliard

Cleaned up the various errno location tests in configure.

Added (h_)errno_location pointers in the library that allow remapping the calls in higher level dlls. Moved X11DRV_CritSection out of sysdeps.c and into x11drv.dll.
parent 4bed8266
...@@ -660,74 +660,35 @@ dnl ...@@ -660,74 +660,35 @@ dnl
dnl For cross-compiling we blindly assume that libc is reentrant. This is dnl For cross-compiling we blindly assume that libc is reentrant. This is
dnl ok since non-reentrant libc is quite rare (mostly old libc5 versions). dnl ok since non-reentrant libc is quite rare (mostly old libc5 versions).
wine_cv_libc_reentrant=no AC_DEFUN(WINE_CHECK_ERRNO,
dnl [
dnl Linux style errno location AC_CACHE_CHECK(for reentrant libc: $1, wine_cv_libc_r_$1,
dnl
AC_CACHE_CHECK("for reentrant libc: __errno_location", wine_cv_libc_r__errno_location,
[AC_TRY_RUN([int myerrno = 0; [AC_TRY_RUN([int myerrno = 0;
char buf[256]; char buf[256];
int *__errno_location(){return &myerrno;} int *$1(){return &myerrno;}
main(){connect(0,buf,255); exit(!myerrno);}], main(){connect(0,buf,255); exit(!myerrno);}],
wine_cv_libc_r__errno_location=yes, wine_cv_libc_r__errno_location=no, wine_cv_libc_r_$1=yes, wine_cv_libc_r_$1=no,
wine_cv_libc_r__errno_location=yes ) wine_cv_libc_r_$1=yes )
]) ])
if test "$wine_cv_libc_r__errno_location" = "yes" if test "$wine_cv_libc_r_$1" = "yes"
then then
AC_DEFINE(HAVE__ERRNO_LOCATION) wine_cv_libc_reentrant=$1
wine_cv_libc_reentrant=__errno_location
fi fi
dnl
dnl FreeBSD style errno location
dnl
AC_CACHE_CHECK("for reentrant libc: __error", wine_cv_libc_r__error,
[AC_TRY_RUN([int myerrno = 0;
char buf[256];
int *__error(){return &myerrno;}
main(){connect(0,buf,255); exit(!myerrno);}],
wine_cv_libc_r__error=yes, wine_cv_libc_r__error=no,
wine_cv_libc_r__error=yes )
]) ])
if test "$wine_cv_libc_r__error" = "yes"
then wine_cv_libc_reentrant=no
AC_DEFINE(HAVE__ERROR) dnl Linux style errno location
wine_cv_libc_reentrant=__error WINE_CHECK_ERRNO(__errno_location)
fi dnl FreeBSD style errno location
dnl WINE_CHECK_ERRNO(__error)
dnl Solaris style errno location dnl Solaris style errno location
dnl WINE_CHECK_ERRNO(___errno)
AC_CACHE_CHECK("for reentrant libc: ___errno", wine_cv_libc_r___errno,
[AC_TRY_RUN([int myerrno = 0;
char buf[256];
int *___errno(){return &myerrno;}
main(){connect(0,buf,255); exit(!myerrno);}],
wine_cv_libc_r___errno=yes, wine_cv_libc_r___errno=no,
wine_cv_libc_r___errno=yes )
])
if test "$wine_cv_libc_r___errno" = "yes"
then
AC_DEFINE(HAVE___ERRNO)
wine_cv_libc_reentrant=___errno
fi
dnl
dnl UnixWare style errno location dnl UnixWare style errno location
dnl WINE_CHECK_ERRNO(__thr_errno)
AC_CACHE_CHECK("for reentrant libc: __thr_errno", wine_cv_libc_r__thr_errno,
[AC_TRY_RUN([int myerrno = 0; if test "$wine_cv_libc_reentrant" != "no"
char buf[256];
int *__thr_errno(){return &myerrno;}
main(){connect(0,buf,255); exit(!myerrno);}],
wine_cv_libc_r__thr_errno=yes, wine_cv_libc_r__thr_errno=no,
wine_cv_libc_r__thr_errno=yes )
])
if test "$wine_cv_libc_r__thr_errno" = "yes"
then
AC_DEFINE(HAVE__THR_ERRNO)
wine_cv_libc_reentrant=__thr_errno
fi
if test "$wine_cv_libc_reentrant" = "no"
then then
AC_DEFINE(NO_REENTRANT_LIBC) AC_DEFINE_UNQUOTED(ERRNO_LOCATION,$wine_cv_libc_reentrant)
fi fi
dnl **** Check for reentrant X libraries **** dnl **** Check for reentrant X libraries ****
......
...@@ -7,6 +7,15 @@ ...@@ -7,6 +7,15 @@
#include "config.h" #include "config.h"
#ifdef NO_REENTRANT_X11
/* Get pointers to the static errno and h_errno variables used by Xlib. This
must be done before including <errno.h> makes the variables invisible. */
extern int errno;
static int *perrno = &errno;
extern int h_errno;
static int *ph_errno = &h_errno;
#endif /* NO_REENTRANT_X11 */
#include <fcntl.h> #include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -36,6 +45,8 @@ static XKeyboardState keyboard_state; ...@@ -36,6 +45,8 @@ static XKeyboardState keyboard_state;
static void (*old_tsx11_lock)(void); static void (*old_tsx11_lock)(void);
static void (*old_tsx11_unlock)(void); static void (*old_tsx11_unlock)(void);
static CRITICAL_SECTION X11DRV_CritSection = CRITICAL_SECTION_INIT;
Display *display; Display *display;
Screen *screen; Screen *screen;
Visual *visual; Visual *visual;
...@@ -46,6 +57,35 @@ Window root_window; ...@@ -46,6 +57,35 @@ Window root_window;
unsigned int X11DRV_server_startticks; unsigned int X11DRV_server_startticks;
#ifdef NO_REENTRANT_X11
static int* (*old_errno_location)(void);
static int* (*old_h_errno_location)(void);
/***********************************************************************
* x11_errno_location
*
* Get the per-thread errno location.
*/
static int *x11_errno_location(void)
{
/* Use static libc errno while running in Xlib. */
if (X11DRV_CritSection.OwningThread == GetCurrentThreadId()) return perrno;
return old_errno_location();
}
/***********************************************************************
* x11_h_errno_location
*
* Get the per-thread h_errno location.
*/
static int *x11_h_errno_location(void)
{
/* Use static libc h_errno while running in Xlib. */
if (X11DRV_CritSection.OwningThread == GetCurrentThreadId()) return ph_errno;
return old_h_errno_location();
}
#endif /* NO_REENTRANT_X11 */
/*********************************************************************** /***********************************************************************
* error_handler * error_handler
*/ */
...@@ -268,6 +308,12 @@ static void process_attach(void) ...@@ -268,6 +308,12 @@ static void process_attach(void)
setup_options(); setup_options();
/* setup TSX11 locking */ /* setup TSX11 locking */
#ifdef NO_REENTRANT_X11
old_errno_location = (void *)InterlockedExchange( (PLONG)&wine_errno_location,
(LONG)x11_errno_location );
old_h_errno_location = (void *)InterlockedExchange( (PLONG)&wine_h_errno_location,
(LONG)x11_h_errno_location );
#endif /* NO_REENTRANT_X11 */
old_tsx11_lock = wine_tsx11_lock; old_tsx11_lock = wine_tsx11_lock;
old_tsx11_unlock = wine_tsx11_unlock; old_tsx11_unlock = wine_tsx11_unlock;
wine_tsx11_lock = lock_tsx11; wine_tsx11_lock = lock_tsx11;
...@@ -359,6 +405,10 @@ static void process_detach(void) ...@@ -359,6 +405,10 @@ static void process_detach(void)
/* restore TSX11 locking */ /* restore TSX11 locking */
wine_tsx11_lock = old_tsx11_lock; wine_tsx11_lock = old_tsx11_lock;
wine_tsx11_unlock = old_tsx11_unlock; wine_tsx11_unlock = old_tsx11_unlock;
#ifdef NO_REENTRANT_X11
wine_errno_location = old_errno_location;
wine_h_errno_location = old_h_errno_location;
#endif /* NO_REENTRANT_X11 */
#if 0 /* FIXME */ #if 0 /* FIXME */
/* close the display */ /* close the display */
......
...@@ -48,20 +48,8 @@ ...@@ -48,20 +48,8 @@
/* Define if X libraries are not reentrant (compiled without -D_REENTRANT). */ /* Define if X libraries are not reentrant (compiled without -D_REENTRANT). */
#undef NO_REENTRANT_X11 #undef NO_REENTRANT_X11
/* Define if libc is not reentrant */ /* Define to the name of the function returning erro for reentrant libc */
#undef NO_REENTRANT_LIBC #undef ERRNO_LOCATION
/* Define if libc uses __errno_location for reentrant errno */
#undef HAVE__ERRNO_LOCATION
/* Define if libc uses __error for reentrant errno */
#undef HAVE__ERROR
/* Define if libc uses ___errno for reentrant errno */
#undef HAVE___ERRNO
/* Define if libc uses __thr_errno for reentrant errno */
#undef HAVE__THR_ERRNO
/* Define if all debug messages are to be compiled out */ /* Define if all debug messages are to be compiled out */
#undef NO_DEBUG_MSGS #undef NO_DEBUG_MSGS
......
...@@ -88,20 +88,8 @@ ...@@ -88,20 +88,8 @@
/* Define if X libraries are not reentrant (compiled without -D_REENTRANT). */ /* Define if X libraries are not reentrant (compiled without -D_REENTRANT). */
#undef NO_REENTRANT_X11 #undef NO_REENTRANT_X11
/* Define if libc is not reentrant */ /* Define to the name of the function returning erro for reentrant libc */
#undef NO_REENTRANT_LIBC #undef ERRNO_LOCATION
/* Define if libc uses __errno_location for reentrant errno */
#undef HAVE__ERRNO_LOCATION
/* Define if libc uses __error for reentrant errno */
#undef HAVE__ERROR
/* Define if libc uses ___errno for reentrant errno */
#undef HAVE___ERRNO
/* Define if libc uses __thr_errno for reentrant errno */
#undef HAVE__THR_ERRNO
/* Define if all debug messages are to be compiled out */ /* Define if all debug messages are to be compiled out */
#undef NO_DEBUG_MSGS #undef NO_DEBUG_MSGS
......
...@@ -27,6 +27,10 @@ extern void wine_dbg_add_option( const char *name, unsigned char set, unsigned c ...@@ -27,6 +27,10 @@ extern void wine_dbg_add_option( const char *name, unsigned char set, unsigned c
extern void *wine_anon_mmap( void *start, size_t size, int prot, int flags ); extern void *wine_anon_mmap( void *start, size_t size, int prot, int flags );
/* errno support */
extern int* (*wine_errno_location)(void);
extern int* (*wine_h_errno_location)(void);
/* LDT management */ /* LDT management */
extern void wine_ldt_get_entry( unsigned short sel, LDT_ENTRY *entry ); extern void wine_ldt_get_entry( unsigned short sel, LDT_ENTRY *entry );
......
...@@ -191,10 +191,6 @@ extern BOOL X11DRV_SetupGCForText( struct tagDC *dc ); ...@@ -191,10 +191,6 @@ extern BOOL X11DRV_SetupGCForText( struct tagDC *dc );
extern const int X11DRV_XROPfunction[]; extern const int X11DRV_XROPfunction[];
/* Xlib critical section */
extern CRITICAL_SECTION X11DRV_CritSection;
extern void _XInitImageFuncPtrs(XImage *); extern void _XInitImageFuncPtrs(XImage *);
#define XCREATEIMAGE(image,width,height,bpp) \ #define XCREATEIMAGE(image,width,height,bpp) \
......
...@@ -10,6 +10,7 @@ SONAME = libwine.so ...@@ -10,6 +10,7 @@ SONAME = libwine.so
C_SRCS = \ C_SRCS = \
debug.c \ debug.c \
errno.c \
ldt.c \ ldt.c \
loader.c \ loader.c \
port.c port.c
......
/*
* Wine library reentrant errno support
*
* Copyright 1998 Alexandre Julliard
*/
/* Get pointers to the static errno and h_errno variables used by Xlib. This
must be done before including <errno.h> makes the variables invisible. */
static int *default_errno_location(void)
{
extern int errno;
return &errno;
}
static int *default_h_errno_location(void)
{
extern int h_errno;
return &h_errno;
}
int* (*wine_errno_location)(void) = default_errno_location;
int* (*wine_h_errno_location)(void) = default_h_errno_location;
#include "config.h"
/***********************************************************************
* __errno_location/__error/___errno
*
* Get the per-thread errno location.
*/
#ifdef ERRNO_LOCATION
int *ERRNO_LOCATION(void)
{
return wine_errno_location();
}
#endif /* ERRNO_LOCATION */
/***********************************************************************
* __h_errno_location
*
* Get the per-thread h_errno location.
*/
int *__h_errno_location(void)
{
return wine_h_errno_location();
}
...@@ -6,13 +6,6 @@ ...@@ -6,13 +6,6 @@
#include "config.h" #include "config.h"
/* Get pointers to the static errno and h_errno variables used by Xlib. This
must be done before including <errno.h> makes the variables invisible. */
extern int errno;
static int *perrno = &errno;
extern int h_errno;
static int *ph_errno = &h_errno;
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
...@@ -36,9 +29,6 @@ static int *ph_errno = &h_errno; ...@@ -36,9 +29,6 @@ static int *ph_errno = &h_errno;
DEFAULT_DEBUG_CHANNEL(thread); DEFAULT_DEBUG_CHANNEL(thread);
/* Xlib critical section (FIXME: does not belong here) */
CRITICAL_SECTION X11DRV_CritSection = CRITICAL_SECTION_INIT;
#ifdef linux #ifdef linux
# ifdef HAVE_SCHED_H # ifdef HAVE_SCHED_H
# include <sched.h> # include <sched.h>
...@@ -52,55 +42,6 @@ CRITICAL_SECTION X11DRV_CritSection = CRITICAL_SECTION_INIT; ...@@ -52,55 +42,6 @@ CRITICAL_SECTION X11DRV_CritSection = CRITICAL_SECTION_INIT;
# endif /* CLONE_VM */ # endif /* CLONE_VM */
#endif /* linux */ #endif /* linux */
static int init_done;
#ifndef NO_REENTRANT_LIBC
/***********************************************************************
* __errno_location/__error/___errno
*
* Get the per-thread errno location.
*/
#ifdef HAVE__ERRNO_LOCATION
int *__errno_location()
#endif
#ifdef HAVE__ERROR
int *__error()
#endif
#ifdef HAVE___ERRNO
int *___errno()
#endif
#ifdef HAVE__THR_ERRNO
int *__thr_errno()
#endif
{
if (!init_done) return perrno;
#ifdef NO_REENTRANT_X11
/* Use static libc errno while running in Xlib. */
if (X11DRV_CritSection.OwningThread == GetCurrentThreadId())
return perrno;
#endif
return &NtCurrentTeb()->thread_errno;
}
/***********************************************************************
* __h_errno_location
*
* Get the per-thread h_errno location.
*/
int *__h_errno_location()
{
if (!init_done) return ph_errno;
#ifdef NO_REENTRANT_X11
/* Use static libc h_errno while running in Xlib. */
if (X11DRV_CritSection.OwningThread == GetCurrentThreadId())
return ph_errno;
#endif
return &NtCurrentTeb()->thread_h_errno;
}
#endif /* NO_REENTRANT_LIBC */
/*********************************************************************** /***********************************************************************
* SYSDEPS_SetCurThread * SYSDEPS_SetCurThread
* *
...@@ -115,8 +56,6 @@ void SYSDEPS_SetCurThread( TEB *teb ) ...@@ -115,8 +56,6 @@ void SYSDEPS_SetCurThread( TEB *teb )
/* On non-i386 Solaris, we use the LWP private pointer */ /* On non-i386 Solaris, we use the LWP private pointer */
_lwp_setprivate( teb ); _lwp_setprivate( teb );
#endif #endif
init_done = 1; /* now we can use threading routines */
} }
/*********************************************************************** /***********************************************************************
...@@ -150,7 +89,7 @@ static void SYSDEPS_StartThread( TEB *teb ) ...@@ -150,7 +89,7 @@ static void SYSDEPS_StartThread( TEB *teb )
*/ */
int SYSDEPS_SpawnThread( TEB *teb ) int SYSDEPS_SpawnThread( TEB *teb )
{ {
#ifndef NO_REENTRANT_LIBC #ifdef ERRNO_LOCATION
#ifdef linux #ifdef linux
const int flags = CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD; const int flags = CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD;
...@@ -192,7 +131,7 @@ int SYSDEPS_SpawnThread( TEB *teb ) ...@@ -192,7 +131,7 @@ int SYSDEPS_SpawnThread( TEB *teb )
return 0; return 0;
#endif #endif
#endif /* NO_REENTRANT_LIBC */ #endif /* ERRNO_LOCATION */
FIXME("CreateThread: stub\n" ); FIXME("CreateThread: stub\n" );
return 0; return 0;
......
...@@ -214,6 +214,26 @@ error: ...@@ -214,6 +214,26 @@ error:
/*********************************************************************** /***********************************************************************
* thread_errno_location
*
* Get the per-thread errno location.
*/
static int *thread_errno_location(void)
{
return &NtCurrentTeb()->thread_errno;
}
/***********************************************************************
* thread_h_errno_location
*
* Get the per-thread h_errno location.
*/
static int *thread_h_errno_location(void)
{
return &NtCurrentTeb()->thread_h_errno;
}
/***********************************************************************
* THREAD_Init * THREAD_Init
* *
* Setup the initial thread. * Setup the initial thread.
...@@ -228,6 +248,8 @@ void THREAD_Init(void) ...@@ -228,6 +248,8 @@ void THREAD_Init(void)
assert( initial_teb.teb_sel ); assert( initial_teb.teb_sel );
initial_teb.process = &current_process; initial_teb.process = &current_process;
SYSDEPS_SetCurThread( &initial_teb ); SYSDEPS_SetCurThread( &initial_teb );
wine_errno_location = thread_errno_location;
wine_h_errno_location = thread_h_errno_location;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment