Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/nathanw_sa]: src/lib/libpthread Work around the fact that the sa_enable(...



details:   https://anonhg.NetBSD.org/src/rev/86d9adccfdd8
branches:  nathanw_sa
changeset: 505508:86d9adccfdd8
user:      nathanw <nathanw%NetBSD.org@localhost>
date:      Wed Jan 02 18:32:02 2002 +0000

description:
Work around the fact that the sa_enable() syscall doesn't really
return from the kernel, but is continued by being jumped to from an
upcall, which can result in stuffing a bogus value into errno.

Fixes errno1 test on i386, and possibly elsewhere.

diffstat:

 lib/libpthread/pthread_sa.c |  21 ++++++++++++++++++---
 1 files changed, 18 insertions(+), 3 deletions(-)

diffs (41 lines):

diff -r 0e865b2e7b82 -r 86d9adccfdd8 lib/libpthread/pthread_sa.c
--- a/lib/libpthread/pthread_sa.c       Wed Jan 02 05:53:43 2002 +0000
+++ b/lib/libpthread/pthread_sa.c       Wed Jan 02 18:32:02 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pthread_sa.c,v 1.1.2.14 2001/12/30 02:20:50 nathanw Exp $      */
+/*     $NetBSD: pthread_sa.c,v 1.1.2.15 2002/01/02 18:32:02 nathanw Exp $      */
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -477,7 +477,7 @@
 {
        pthread_t t;
        stack_t upcall_stacks[PT_UPCALLSTACKS];
-       int ret, i;
+       int ret, i, errnosave;
 
        ret = sa_register(pthread__upcall, NULL);
        if (ret)
@@ -501,6 +501,21 @@
        if (ret == -1)
                err(1, "sa_stacks failed");
 
+       /* XXX 
+        * Calling sa_enable() can mess with errno in bizzare ways,
+        * because the kernel doesn't really return from it as a
+        * normal system call. The kernel will launch an upcall
+        * handler which will jump back to the inside of sa_enable()
+        * and permit us to continue here. However, since the kernel
+        * doesn't get a chance to set up the return-state properly,
+        * the syscall stub may interpret the unmodified register
+        * state as an error return and stuff an inappropriate value
+        * into errno.
+        *
+        * Therefore, we need to keep errno from being changed by this
+        * slightly weird control flow.
+        */
+       errnosave = errno;
        sa_enable();
-
+       errno = errnosave;
 }



Home | Main Index | Thread Index | Old Index