Source-Changes-HG archive

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

[src/netbsd-3]: src/lib/libpthread Pullup revs 1.12-1.13 (requested by chs in...



details:   https://anonhg.NetBSD.org/src/rev/5b25cd5d975f
branches:  netbsd-3
changeset: 577424:5b25cd5d975f
user:      jmc <jmc%NetBSD.org@localhost>
date:      Tue Nov 01 20:01:31 2005 +0000

description:
Pullup revs 1.12-1.13 (requested by chs in ticket #926)
 In pthread_mutex_lock_slow(), pthread_rwlock_timedrdlock() and sem_wait(),
 call pthread__start() if it hasn't already been called. this avoids
 an internal assertion from the library if these routines are used
 before any threads are created and they need to sleep.
 PR#20256, PR#24241, PR#25722, PR#26096

 Fix the interaction between sigtimedwait() and pthread_kill(),
 both waking up a sleeping thread and avoiding going to sleep if
 a signal is already pending. PR#30348

 In pthread_kill() and pthread_suspend_np(), return without doing anything
 f the target thread is a zombie.
 In all the functions that didn't do so already, verify a pthread_t before
 dereferencing it (under #ifdef ERRORCHECK, since these checks are not
 mandated by the standard).

 Starting the pthread library (ie. calling pthread__start()) before
 any threads are created turned out to be not such a good idea.
 there are stronger requirements on what has to work in a forked child
 while a process is still single-threaded. so take all that stuff
 back out and fix the problems with single-threaded programs that
 are linked with libpthread differently, by checking if the library
 has been started and doing completely different stuff if it hasn't been:
 - for pthread_rwlock_timedrdlock(), just fail with EDEADLK immediately.
 - for sem_wait(), the only thing that can unlock the semaphore is a
 signal handler, so use sigsuspend() to wait for a signal.
 - for pthread_mutex_lock_slow(), just go into an infinite loop
 waiting for signals.

 If mlock() fails in pthread_create(), return EAGAIN instead of
 failing an assertion.

diffstat:

 lib/libpthread/pthread_rwlock.c |  27 ++++++++++++++++++++++-----
 1 files changed, 22 insertions(+), 5 deletions(-)

diffs (93 lines):

diff -r 0a183f87e0e2 -r 5b25cd5d975f lib/libpthread/pthread_rwlock.c
--- a/lib/libpthread/pthread_rwlock.c   Mon Oct 31 13:30:33 2005 +0000
+++ b/lib/libpthread/pthread_rwlock.c   Tue Nov 01 20:01:31 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pthread_rwlock.c,v 1.11 2005/01/09 01:57:38 nathanw Exp $ */
+/*     $NetBSD: pthread_rwlock.c,v 1.11.2.1 2005/11/01 20:01:31 jmc Exp $ */
 
 /*-
  * Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread_rwlock.c,v 1.11 2005/01/09 01:57:38 nathanw Exp $");
+__RCSID("$NetBSD: pthread_rwlock.c,v 1.11.2.1 2005/11/01 20:01:31 jmc Exp $");
 
 #include <errno.h>
 
@@ -169,6 +169,8 @@
 pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
 {
        pthread_t self;
+       extern int pthread__started;
+
 #ifdef ERRORCHECK
        if ((rwlock == NULL) || (rwlock->ptr_magic != _PT_RWLOCK_MAGIC))
                return EINVAL;
@@ -187,6 +189,12 @@
         * waiting readers.
         */
        while ((rwlock->ptr_nreaders > 0) || (rwlock->ptr_writer != NULL)) {
+#ifdef ERRORCHECK
+               if (pthread__started == 0) {
+                       pthread_spinunlock(self, &rwlock->ptr_interlock);
+                       return EDEADLK;
+               }
+#endif
                PTQ_INSERT_TAIL(&rwlock->ptr_wblocked, self, pt_sleep);
                /* Locking a rwlock is not a cancellation point; don't check */
                pthread_spinlock(self, &self->pt_statelock);
@@ -248,6 +256,7 @@
        struct pthread_rwlock__waitarg wait;
        struct pt_alarm_t alarm;
        int retval;
+
 #ifdef ERRORCHECK
        if ((rwlock == NULL) || (rwlock->ptr_magic != _PT_RWLOCK_MAGIC))
                return EINVAL;
@@ -258,8 +267,8 @@
            (abs_timeout->tv_nsec < 0) ||
            (abs_timeout->tv_sec < 0))
                return EINVAL;
+
        self = pthread__self();
-       
        pthread_spinlock(self, &rwlock->ptr_interlock);
 #ifdef ERRORCHECK
        if (rwlock->ptr_writer == self) {
@@ -316,8 +325,10 @@
 {
        struct pthread_rwlock__waitarg wait;
        struct pt_alarm_t alarm;
+       pthread_t self;
        int retval;
-       pthread_t self;
+       extern int pthread__started;
+
 #ifdef ERRORCHECK
        if ((rwlock == NULL) || (rwlock->ptr_magic != _PT_RWLOCK_MAGIC))
                return EINVAL;
@@ -328,8 +339,8 @@
            (abs_timeout->tv_nsec < 0) ||
            (abs_timeout->tv_sec < 0))
                return EINVAL;
+
        self = pthread__self();
-       
        pthread_spinlock(self, &rwlock->ptr_interlock);
 #ifdef ERRORCHECK
        if (rwlock->ptr_writer == self) {
@@ -344,6 +355,12 @@
        retval = 0;
        while (retval == 0 &&
            ((rwlock->ptr_nreaders > 0) || (rwlock->ptr_writer != NULL))) {
+#ifdef ERRORCHECK
+               if (pthread__started == 0) {
+                       pthread_spinunlock(self, &rwlock->ptr_interlock);
+                       return EDEADLK;
+               }
+#endif
                wait.ptw_thread = self;
                wait.ptw_rwlock = rwlock;
                wait.ptw_queue = &rwlock->ptr_wblocked;



Home | Main Index | Thread Index | Old Index