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.8-1.9 (requested by chs in t...
details: https://anonhg.NetBSD.org/src/rev/07b8448b8f6e
branches: netbsd-3
changeset: 577428:07b8448b8f6e
user: jmc <jmc%NetBSD.org@localhost>
date: Tue Nov 01 20:01:44 2005 +0000
description:
Pullup revs 1.8-1.9 (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/sem.c | 38 ++++++++++++++++++++++++++++++++++++--
1 files changed, 36 insertions(+), 2 deletions(-)
diffs (80 lines):
diff -r 6e537e2c4c56 -r 07b8448b8f6e lib/libpthread/sem.c
--- a/lib/libpthread/sem.c Tue Nov 01 20:01:41 2005 +0000
+++ b/lib/libpthread/sem.c Tue Nov 01 20:01:44 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sem.c,v 1.7 2003/11/24 23:54:13 cl Exp $ */
+/* $NetBSD: sem.c,v 1.7.6.1 2005/11/01 20:01:44 jmc Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: sem.c,v 1.7 2003/11/24 23:54:13 cl Exp $");
+__RCSID("$NetBSD: sem.c,v 1.7.6.1 2005/11/01 20:01:44 jmc Exp $");
#include <sys/types.h>
#include <sys/ksem.h>
@@ -286,6 +286,7 @@
sem_wait(sem_t *sem)
{
pthread_t self;
+ extern int pthread__started;
#ifdef ERRORCHECK
if (sem == NULL || *sem == NULL || (*sem)->usem_magic != USEM_MAGIC) {
@@ -301,6 +302,22 @@
return (_ksem_wait((*sem)->usem_semid));
}
+ if (pthread__started == 0) {
+ sigset_t set, oset;
+
+ sigfillset(&set);
+ (void) sigprocmask(SIG_SETMASK, &set, &oset);
+ for (;;) {
+ if ((*sem)->usem_count > 0) {
+ break;
+ }
+ (void) sigsuspend(&oset);
+ }
+ (*sem)->usem_count--;
+ (void) sigprocmask(SIG_SETMASK, &oset, NULL);
+ return 0;
+ }
+
for (;;) {
pthread_spinlock(self, &(*sem)->usem_interlock);
pthread_spinlock(self, &self->pt_statelock);
@@ -339,6 +356,7 @@
sem_trywait(sem_t *sem)
{
pthread_t self;
+ extern int pthread__started;
#ifdef ERRORCHECK
if (sem == NULL || *sem == NULL || (*sem)->usem_magic != USEM_MAGIC) {
@@ -350,6 +368,22 @@
if ((*sem)->usem_semid != USEM_USER)
return (_ksem_trywait((*sem)->usem_semid));
+ if (pthread__started == 0) {
+ sigset_t set, oset;
+ int rv = 0;
+
+ sigfillset(&set);
+ (void) sigprocmask(SIG_SETMASK, &set, &oset);
+ if ((*sem)->usem_count > 0) {
+ (*sem)->usem_count--;
+ } else {
+ errno = EAGAIN;
+ rv = -1;
+ }
+ (void) sigprocmask(SIG_SETMASK, &oset, NULL);
+ return rv;
+ }
+
self = pthread__self();
pthread_spinlock(self, &(*sem)->usem_interlock);
Home |
Main Index |
Thread Index |
Old Index