Merged Linux/FreeBSD reentrant errno handler, added Solaris.
Preliminary support for Solaris low-level threads (LWPs) added.
diff --git a/scheduler/sysdeps.c b/scheduler/sysdeps.c
index a579aef..002462d 100644
--- a/scheduler/sysdeps.c
+++ b/scheduler/sysdeps.c
@@ -19,11 +19,20 @@
#ifdef HAVE_SYS_SYSCALL_H
# include <sys/syscall.h>
#endif
+#ifdef HAVE_SYS_LWP_H
+# include <sys/lwp.h>
+#endif
+#ifdef HAVE_UCONTEXT_H
+# include <ucontext.h>
+#endif
#include "thread.h"
#include "server.h"
#include "winbase.h"
#include "debug.h"
+#ifdef linux
+#define HAVE_CLONE_SYSCALL
+#endif
/* Xlib critical section (FIXME: does not belong here) */
CRITICAL_SECTION X11DRV_CritSection = { 0, };
@@ -44,14 +53,22 @@
#endif /* HAVE_CLONE_SYSCALL */
-#ifdef USE_THREADS
-#ifdef linux
+#ifndef NO_REENTRANT_LIBC
+
/***********************************************************************
- * __errno_location
+ * __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
{
THDB *thdb = THREAD_Current();
if (!thdb) return perrno;
@@ -79,20 +96,8 @@
#endif
return &thdb->thread_h_errno;
}
-#endif
-#ifdef __FreeBSD__
-int *__error() {
- THDB *thdb = THREAD_Current();
- if (!thdb) return perrno;
-#ifdef NO_REENTRANT_X11
- /* Use static libc errno while running in Xlib. */
- if (X11DRV_CritSection.OwningThread == (HANDLE)thdb->server_tid)
- return perrno;
-#endif
- return &thdb->thread_errno;
-}
-#endif
+#endif /* NO_REENTRANT_LIBC */
/***********************************************************************
* SYSDEPS_StartThread
@@ -106,7 +111,6 @@
thdb->startup();
_exit(0); /* should never get here */
}
-#endif /* USE_THREADS */
/***********************************************************************
@@ -117,7 +121,7 @@
*/
int SYSDEPS_SpawnThread( THDB *thread )
{
-#ifdef USE_THREADS
+#ifndef NO_REENTRANT_LIBC
#ifdef HAVE_CLONE_SYSCALL
if (clone( (int (*)(void *))SYSDEPS_StartThread, thread->teb.stack_top,
@@ -125,6 +129,7 @@
return -1;
/* FIXME: close the child socket in the parent process */
/* close( thread->socket );*/
+ return 0;
#endif
#ifdef HAVE_RFORK
@@ -145,15 +150,26 @@
"addl $8,%%esp" :
: "r" (sp), "g" (SYS_rfork), "g" (RFPROC|RFMEM)
: "eax", "edx");
+ return 0;
#endif
-#else /* !USE_THREADS */
+#ifdef HAVE__LWP_CREATE
+ ucontext_t context;
+ _lwp_makecontext( &context, (void(*)(void *))SYSDEPS_StartThread, thread,
+ NULL, thread->stack_base, thread->teb.stack_top - thread->stack_base );
+ if ( _lwp_create( &context, 0, NULL ) )
+ return -1;
+ return 0;
+#endif
+
+#endif /* NO_REENTRANT_LIBC */
+
FIXME(thread, "CreateThread: stub\n" );
-#endif /* USE_THREADS */
return 0;
}
+
/***********************************************************************
* SYSDEPS_ExitThread
*
@@ -163,6 +179,10 @@
*/
void SYSDEPS_ExitThread(void)
{
+#ifdef HAVE__LWP_CREATE
+ _lwp_exit();
+#endif
+
_exit( 0 );
}