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
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).
wine_cv_libc_reentrant=no
dnl
dnl Linux style errno location
dnl
AC_CACHE_CHECK("for reentrant libc: __errno_location", wine_cv_libc_r__errno_location,
AC_DEFUN(WINE_CHECK_ERRNO,
[
AC_CACHE_CHECK(for reentrant libc: $1, wine_cv_libc_r_$1,
[AC_TRY_RUN([int myerrno = 0;
char buf[256];
int *__errno_location(){return &myerrno;}
int *$1(){return &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__errno_location=yes )
wine_cv_libc_r_$1=yes, wine_cv_libc_r_$1=no,
wine_cv_libc_r_$1=yes )
])
if test "$wine_cv_libc_r__errno_location" = "yes"
if test "$wine_cv_libc_r_$1" = "yes"
then
AC_DEFINE(HAVE__ERRNO_LOCATION)
wine_cv_libc_reentrant=__errno_location
wine_cv_libc_reentrant=$1
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
AC_DEFINE(HAVE__ERROR)
wine_cv_libc_reentrant=__error
fi
dnl
wine_cv_libc_reentrant=no
dnl Linux style errno location
WINE_CHECK_ERRNO(__errno_location)
dnl FreeBSD style errno location
WINE_CHECK_ERRNO(__error)
dnl Solaris style errno location
dnl
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
WINE_CHECK_ERRNO(___errno)
dnl UnixWare style errno location
dnl
AC_CACHE_CHECK("for reentrant libc: __thr_errno", wine_cv_libc_r__thr_errno,
[AC_TRY_RUN([int myerrno = 0;
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"
WINE_CHECK_ERRNO(__thr_errno)
if test "$wine_cv_libc_reentrant" != "no"
then
AC_DEFINE(NO_REENTRANT_LIBC)
AC_DEFINE_UNQUOTED(ERRNO_LOCATION,$wine_cv_libc_reentrant)
fi
dnl **** Check for reentrant X libraries ****
......
......@@ -7,6 +7,15 @@
#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 <stdio.h>
#include <stdlib.h>
......@@ -36,6 +45,8 @@ static XKeyboardState keyboard_state;
static void (*old_tsx11_lock)(void);
static void (*old_tsx11_unlock)(void);
static CRITICAL_SECTION X11DRV_CritSection = CRITICAL_SECTION_INIT;
Display *display;
Screen *screen;
Visual *visual;
......@@ -46,6 +57,35 @@ Window root_window;
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
*/
......@@ -268,6 +308,12 @@ static void process_attach(void)
setup_options();
/* 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_unlock = wine_tsx11_unlock;
wine_tsx11_lock = lock_tsx11;
......@@ -359,6 +405,10 @@ static void process_detach(void)
/* restore TSX11 locking */
wine_tsx11_lock = old_tsx11_lock;
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 */
/* close the display */
......
......@@ -48,20 +48,8 @@
/* Define if X libraries are not reentrant (compiled without -D_REENTRANT). */
#undef NO_REENTRANT_X11
/* Define if libc is not reentrant */
#undef NO_REENTRANT_LIBC
/* 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 to the name of the function returning erro for reentrant libc */
#undef ERRNO_LOCATION
/* Define if all debug messages are to be compiled out */
#undef NO_DEBUG_MSGS
......
......@@ -88,20 +88,8 @@
/* Define if X libraries are not reentrant (compiled without -D_REENTRANT). */
#undef NO_REENTRANT_X11
/* Define if libc is not reentrant */
#undef NO_REENTRANT_LIBC
/* 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 to the name of the function returning erro for reentrant libc */
#undef ERRNO_LOCATION
/* Define if all debug messages are to be compiled out */
#undef NO_DEBUG_MSGS
......
......@@ -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 );
/* errno support */
extern int* (*wine_errno_location)(void);
extern int* (*wine_h_errno_location)(void);
/* LDT management */
extern void wine_ldt_get_entry( unsigned short sel, LDT_ENTRY *entry );
......
......@@ -191,10 +191,6 @@ extern BOOL X11DRV_SetupGCForText( struct tagDC *dc );
extern const int X11DRV_XROPfunction[];
/* Xlib critical section */
extern CRITICAL_SECTION X11DRV_CritSection;
extern void _XInitImageFuncPtrs(XImage *);
#define XCREATEIMAGE(image,width,height,bpp) \
......
......@@ -10,6 +10,7 @@ SONAME = libwine.so
C_SRCS = \
debug.c \
errno.c \
ldt.c \
loader.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 @@
#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 <stdio.h>
#include <unistd.h>
......@@ -36,9 +29,6 @@ static int *ph_errno = &h_errno;
DEFAULT_DEBUG_CHANNEL(thread);
/* Xlib critical section (FIXME: does not belong here) */
CRITICAL_SECTION X11DRV_CritSection = CRITICAL_SECTION_INIT;
#ifdef linux
# ifdef HAVE_SCHED_H
# include <sched.h>
......@@ -52,55 +42,6 @@ CRITICAL_SECTION X11DRV_CritSection = CRITICAL_SECTION_INIT;
# endif /* CLONE_VM */
#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
*
......@@ -115,8 +56,6 @@ void SYSDEPS_SetCurThread( TEB *teb )
/* On non-i386 Solaris, we use the LWP private pointer */
_lwp_setprivate( teb );
#endif
init_done = 1; /* now we can use threading routines */
}
/***********************************************************************
......@@ -150,7 +89,7 @@ static void SYSDEPS_StartThread( TEB *teb )
*/
int SYSDEPS_SpawnThread( TEB *teb )
{
#ifndef NO_REENTRANT_LIBC
#ifdef ERRNO_LOCATION
#ifdef linux
const int flags = CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD;
......@@ -192,7 +131,7 @@ int SYSDEPS_SpawnThread( TEB *teb )
return 0;
#endif
#endif /* NO_REENTRANT_LIBC */
#endif /* ERRNO_LOCATION */
FIXME("CreateThread: stub\n" );
return 0;
......
......@@ -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
*
* Setup the initial thread.
......@@ -228,6 +248,8 @@ void THREAD_Init(void)
assert( initial_teb.teb_sel );
initial_teb.process = &current_process;
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