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