summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFederico G. Schwindt <fgsch@cvs.openbsd.org>2001-12-19 02:02:53 +0000
committerFederico G. Schwindt <fgsch@cvs.openbsd.org>2001-12-19 02:02:53 +0000
commiteda62f0bd378e59f8f8834ff5aa82b6116d16f3c (patch)
treec86efedef1e44a31c0ca350e46c9ccbd266c7a84
parenta0b122637ad74506e34f0e1c7da4d51b152b73d9 (diff)
More sync.
-rw-r--r--lib/libc_r/uthread/pthread_private.h72
-rw-r--r--lib/libc_r/uthread/uthread_cancel.c47
-rw-r--r--lib/libc_r/uthread/uthread_exit.c4
-rw-r--r--lib/libc_r/uthread/uthread_join.c3
-rw-r--r--lib/libc_r/uthread/uthread_resume_np.c41
-rw-r--r--lib/libpthread/uthread/pthread_private.h72
-rw-r--r--lib/libpthread/uthread/uthread_cancel.c47
-rw-r--r--lib/libpthread/uthread/uthread_exit.c4
-rw-r--r--lib/libpthread/uthread/uthread_join.c3
-rw-r--r--lib/libpthread/uthread/uthread_resume_np.c41
10 files changed, 246 insertions, 88 deletions
diff --git a/lib/libc_r/uthread/pthread_private.h b/lib/libc_r/uthread/pthread_private.h
index b5556c44ffe..af234ac6c7d 100644
--- a/lib/libc_r/uthread/pthread_private.h
+++ b/lib/libc_r/uthread/pthread_private.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pthread_private.h,v 1.31 2001/12/11 00:19:47 fgsch Exp $ */
+/* $OpenBSD: pthread_private.h,v 1.32 2001/12/19 02:02:52 fgsch Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -120,6 +120,14 @@
* called with preemption deferred (see thread_kern_sched_[un]defer).
*/
#if defined(_PTHREADS_INVARIANTS)
+#include <assert.h>
+#define PTHREAD_ASSERT(cond, msg) do { \
+ if (!(cond)) \
+ PANIC(msg); \
+} while (0)
+#define PTHREAD_ASSERT_NOT_IN_SYNCQ(thrd) \
+ PTHREAD_ASSERT((((thrd)->flags & PTHREAD_FLAGS_IN_SYNCQ) == 0), \
+ "Illegal call from signal handler");
#define PTHREAD_NEW_STATE(thrd, newstate) do { \
if (_thread_kern_new_state != 0) \
PANIC("Recursive PTHREAD_NEW_STATE"); \
@@ -137,6 +145,8 @@
PTHREAD_SET_STATE(thrd, newstate); \
} while (0)
#else
+#define PTHREAD_ASSERT(cond, msg)
+#define PTHREAD_ASSERT_NOT_IN_SYNCQ(thrd)
#define PTHREAD_NEW_STATE(thrd, newstate) do { \
if ((thrd)->state != newstate) { \
if ((thrd)->state == PS_RUNNING) { \
@@ -645,7 +655,7 @@ struct pthread {
int error;
/*
- * The joiner is the thread that is joining this thraed. The
+ * The joiner is the thread that is joining to this thread. The
* join status keeps track of a join operation to another thread.
*/
struct pthread *joiner;
@@ -653,8 +663,7 @@ struct pthread {
/*
* The current thread can belong to only one scheduling queue at
- * a time (ready or waiting queue). It can also belong to (only)
- * one of:
+ * a time (ready or waiting queue). It can also belong to:
*
* o A queue of threads waiting for a mutex
* o A queue of threads waiting for a condition variable
@@ -662,18 +671,25 @@ struct pthread {
* o A queue of threads needing work done by the kernel thread
* (waiting for a spinlock or file I/O)
*
+ * A thread can also be joining a thread (the joiner field above).
+ *
+ * It must not be possible for a thread to belong to any of the
+ * above queues while it is handling a signal. Signal handlers
+ * may longjmp back to previous stack frames circumventing normal
+ * control flow. This could corrupt queue integrity if the thread
+ * retains membership in the queue. Therefore, if a thread is a
+ * member of one of these queues when a signal handler is invoked,
+ * it must remove itself from the queue before calling the signal
+ * handler and reinsert itself after normal return of the handler.
+ *
* Use pqe for the scheduling queue link (both ready and waiting),
- * and qe for other links.
+ * sqe for synchronization (mutex and condition variable) queue
+ * links, and qe for all other links.
*/
- /* Priority queue entry for this thread: */
- pthread_entry_t pqe;
-
- /* Priority queue entry for this thread: */
- pthread_entry_t sqe;
-
- /* Queue entry for this thread: */
- pthread_entry_t qe;
+ pthread_entry_t pqe; /* priority queue link */
+ pthread_entry_t sqe; /* synchronization queue link */
+ pthread_entry_t qe; /* all other queues link */
/* Wait data. */
union pthread_wait_data data;
@@ -704,19 +720,19 @@ struct pthread {
*/
int yield_on_sig_undefer;
- /* Miscellaneous data. */
+ /* Miscellaneous flags; only set with signals deferred. */
int flags;
#define PTHREAD_FLAGS_PRIVATE 0x0001
#define PTHREAD_EXITING 0x0002
-#define PTHREAD_FLAGS_IN_WAITQ 0x0004 /* in waiting queue using pqe link*/
-#define PTHREAD_FLAGS_IN_PRIOQ 0x0008 /* in priority queue using pqe link*/
+#define PTHREAD_FLAGS_IN_WAITQ 0x0004 /* in waiting queue using pqe link */
+#define PTHREAD_FLAGS_IN_PRIOQ 0x0008 /* in priority queue using pqe link */
#define PTHREAD_FLAGS_IN_WORKQ 0x0010 /* in work queue using qe link */
#define PTHREAD_FLAGS_IN_FILEQ 0x0020 /* in file lock queue using qe link */
#define PTHREAD_FLAGS_IN_FDQ 0x0040 /* in fd lock queue using qe link */
-#define PTHREAD_FLAGS_IN_CONDQ 0x0080 /* in condition queue using sqe link*/
-#define PTHREAD_FLAGS_IN_MUTEXQ 0x0100 /* in mutex queue using sqe link*/
+#define PTHREAD_FLAGS_IN_CONDQ 0x0080 /* in condition queue using sqe link */
+#define PTHREAD_FLAGS_IN_MUTEXQ 0x0100 /* in mutex queue using sqe link */
#define PTHREAD_FLAGS_TRACE 0x0200 /* for debugging purposes */
-#define PTHREAD_FLAGS_IN_SYNQ \
+#define PTHREAD_FLAGS_IN_SYNCQ \
(PTHREAD_FLAGS_IN_CONDQ | PTHREAD_FLAGS_IN_MUTEXQ)
/*
@@ -992,6 +1008,21 @@ SCLASS volatile int _spinblock_count
#endif
;
+/* Used to maintain pending and active signals: */
+struct sigstatus {
+ int pending; /* Is this a pending signal? */
+ int blocked; /*
+ * A handler is currently active for
+ * this signal; ignore subsequent
+ * signals until the handler is done.
+ */
+ int signo; /* arg 1 to signal handler */
+ siginfo_t siginfo; /* arg 2 to signal handler */
+ struct sigcontext uc; /* arg 3 to signal handler */
+};
+
+SCLASS struct sigstatus _thread_sigq[NSIG];
+
/* Indicates that the signal queue needs to be checked. */
SCLASS volatile int _sigq_check_reqd
#ifdef GLOBAL_PTHREAD_PRIVATE
@@ -999,6 +1030,9 @@ SCLASS volatile int _sigq_check_reqd
#endif
;
+/* The signal stack. */
+SCLASS struct sigaltstack _thread_sigstack;
+
/* Thread switch hook. */
SCLASS pthread_switch_routine_t _sched_switch_hook
#ifdef GLOBAL_PTHREAD_PRIVATE
diff --git a/lib/libc_r/uthread/uthread_cancel.c b/lib/libc_r/uthread/uthread_cancel.c
index 8c8515dbbc7..29f3a8edebf 100644
--- a/lib/libc_r/uthread/uthread_cancel.c
+++ b/lib/libc_r/uthread/uthread_cancel.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_cancel.c,v 1.8 2001/12/11 00:19:47 fgsch Exp $ */
+/* $OpenBSD: uthread_cancel.c,v 1.9 2001/12/19 02:02:52 fgsch Exp $ */
/*
* David Leonard <d@openbsd.org>, 1999. Public domain.
*/
@@ -59,17 +59,6 @@ pthread_cancel(pthread)
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
break;
- case PS_MUTEX_WAIT:
- case PS_COND_WAIT:
- case PS_FDLR_WAIT:
- case PS_FDLW_WAIT:
- case PS_FILE_WAIT:
- pthread->interrupted = 1;
- pthread->cancelflags |= PTHREAD_CANCEL_NEEDED;
- PTHREAD_NEW_STATE(pthread,PS_RUNNING);
- pthread->continuation = finish_cancellation;
- break;
-
case PS_JOIN:
/*
* Disconnect the thread from the joinee and
@@ -85,9 +74,39 @@ pthread_cancel(pthread)
break;
case PS_SUSPENDED:
- /* Simply wake: */
- /* XXX may be incorrect */
+ if (pthread->suspended == SUSP_NO ||
+ pthread->suspended == SUSP_YES ||
+ pthread->suspended == SUSP_JOIN ||
+ pthread->suspended == SUSP_NOWAIT) {
+ /*
+ * This thread isn't in any scheduling
+ * queues; just change it's state:
+ */
+ pthread->cancelflags |=
+ PTHREAD_CANCELLING;
+ PTHREAD_SET_STATE(pthread, PS_RUNNING);
+ break;
+ }
+ /* FALLTHROUGH */
+ case PS_MUTEX_WAIT:
+ case PS_COND_WAIT:
+ case PS_FDLR_WAIT:
+ case PS_FDLW_WAIT:
+ case PS_FILE_WAIT:
+ /*
+ * Threads in these states may be in queues.
+ * In order to preserve queue integrity, the
+ * cancelled thread must remove itself from the
+ * queue. Mark the thread as interrupted and
+ * needing cancellation, and set the state to
+ * running. When the thread resumes, it will
+ * remove itself from the queue and call the
+ * cancellation completion routine.
+ */
+ pthread->interrupted = 1;
+ pthread->cancelflags |= PTHREAD_CANCEL_NEEDED;
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ pthread->continuation = finish_cancellation;
break;
case PS_DEAD:
diff --git a/lib/libc_r/uthread/uthread_exit.c b/lib/libc_r/uthread/uthread_exit.c
index 232b55e008e..a7a0c60a267 100644
--- a/lib/libc_r/uthread/uthread_exit.c
+++ b/lib/libc_r/uthread/uthread_exit.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_exit.c,v 1.14 2001/12/11 00:19:47 fgsch Exp $ */
+/* $OpenBSD: uthread_exit.c,v 1.15 2001/12/19 02:02:52 fgsch Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -226,11 +226,9 @@ pthread_exit(void *status)
pthread->join_status.error = 0;
pthread->join_status.thread = NULL;
-#ifdef notyet
/* Make this thread collectable by the garbage collector. */
PTHREAD_ASSERT(((curthread->attr.flags & PTHREAD_DETACHED) ==
0), "Cannot join a detached thread");
-#endif
curthread->attr.flags |= PTHREAD_DETACHED;
}
diff --git a/lib/libc_r/uthread/uthread_join.c b/lib/libc_r/uthread/uthread_join.c
index 1cf1624a884..0167427b570 100644
--- a/lib/libc_r/uthread/uthread_join.c
+++ b/lib/libc_r/uthread/uthread_join.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_join.c,v 1.8 2001/12/11 00:19:47 fgsch Exp $ */
+/* $OpenBSD: uthread_join.c,v 1.9 2001/12/19 02:02:52 fgsch Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -134,7 +134,6 @@ pthread_join(pthread_t pthread, void **thread_return)
* joining to when it exits or detaches:
*/
ret = curthread->join_status.error;
- ret = curthread->join_status.error;
if ((ret == 0) && (thread_return != NULL))
*thread_return = curthread->join_status.ret;
} else {
diff --git a/lib/libc_r/uthread/uthread_resume_np.c b/lib/libc_r/uthread/uthread_resume_np.c
index 8816f76e4c8..ace16df8e45 100644
--- a/lib/libc_r/uthread/uthread_resume_np.c
+++ b/lib/libc_r/uthread/uthread_resume_np.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_resume_np.c,v 1.4 1999/11/25 07:01:42 d Exp $ */
+/* $OpenBSD: uthread_resume_np.c,v 1.5 2001/12/19 02:02:52 fgsch Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -41,20 +41,49 @@
int
pthread_resume_np(pthread_t thread)
{
- int ret;
+ int ret;
+ enum pthread_susp old_suspended;
/* Find the thread in the list of active threads: */
if ((ret = _find_thread(thread)) == 0) {
- /* The thread exists. Is it suspended? */
- if (thread->state != PS_SUSPENDED) {
+ /* Cancel any pending suspensions: */
+ old_suspended = thread->suspended;
+ thread->suspended = SUSP_NO;
+
+ /* Is it currently suspended? */
+ if (thread->state == PS_SUSPENDED) {
/*
* Defer signals to protect the scheduling queues
* from access by the signal handler:
*/
_thread_kern_sig_defer();
- /* Allow the thread to run. */
- PTHREAD_NEW_STATE(thread,PS_RUNNING);
+ switch (old_suspended) {
+ case SUSP_MUTEX_WAIT:
+ /* Set the thread's state back. */
+ PTHREAD_SET_STATE(thread,PS_MUTEX_WAIT);
+ break;
+ case SUSP_COND_WAIT:
+ /* Set the thread's state back. */
+ PTHREAD_SET_STATE(thread,PS_COND_WAIT);
+ break;
+ case SUSP_JOIN:
+ /* Set the thread's state back. */
+ PTHREAD_SET_STATE(thread,PS_JOIN);
+ break;
+ case SUSP_NOWAIT:
+ /* Allow the thread to run. */
+ PTHREAD_SET_STATE(thread,PS_RUNNING);
+ PTHREAD_WAITQ_REMOVE(thread);
+ PTHREAD_PRIOQ_INSERT_TAIL(thread);
+ break;
+ case SUSP_NO:
+ case SUSP_YES:
+ /* Allow the thread to run. */
+ PTHREAD_SET_STATE(thread,PS_RUNNING);
+ PTHREAD_PRIOQ_INSERT_TAIL(thread);
+ break;
+ }
/*
* Undefer and handle pending signals, yielding if
diff --git a/lib/libpthread/uthread/pthread_private.h b/lib/libpthread/uthread/pthread_private.h
index b5556c44ffe..af234ac6c7d 100644
--- a/lib/libpthread/uthread/pthread_private.h
+++ b/lib/libpthread/uthread/pthread_private.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pthread_private.h,v 1.31 2001/12/11 00:19:47 fgsch Exp $ */
+/* $OpenBSD: pthread_private.h,v 1.32 2001/12/19 02:02:52 fgsch Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -120,6 +120,14 @@
* called with preemption deferred (see thread_kern_sched_[un]defer).
*/
#if defined(_PTHREADS_INVARIANTS)
+#include <assert.h>
+#define PTHREAD_ASSERT(cond, msg) do { \
+ if (!(cond)) \
+ PANIC(msg); \
+} while (0)
+#define PTHREAD_ASSERT_NOT_IN_SYNCQ(thrd) \
+ PTHREAD_ASSERT((((thrd)->flags & PTHREAD_FLAGS_IN_SYNCQ) == 0), \
+ "Illegal call from signal handler");
#define PTHREAD_NEW_STATE(thrd, newstate) do { \
if (_thread_kern_new_state != 0) \
PANIC("Recursive PTHREAD_NEW_STATE"); \
@@ -137,6 +145,8 @@
PTHREAD_SET_STATE(thrd, newstate); \
} while (0)
#else
+#define PTHREAD_ASSERT(cond, msg)
+#define PTHREAD_ASSERT_NOT_IN_SYNCQ(thrd)
#define PTHREAD_NEW_STATE(thrd, newstate) do { \
if ((thrd)->state != newstate) { \
if ((thrd)->state == PS_RUNNING) { \
@@ -645,7 +655,7 @@ struct pthread {
int error;
/*
- * The joiner is the thread that is joining this thraed. The
+ * The joiner is the thread that is joining to this thread. The
* join status keeps track of a join operation to another thread.
*/
struct pthread *joiner;
@@ -653,8 +663,7 @@ struct pthread {
/*
* The current thread can belong to only one scheduling queue at
- * a time (ready or waiting queue). It can also belong to (only)
- * one of:
+ * a time (ready or waiting queue). It can also belong to:
*
* o A queue of threads waiting for a mutex
* o A queue of threads waiting for a condition variable
@@ -662,18 +671,25 @@ struct pthread {
* o A queue of threads needing work done by the kernel thread
* (waiting for a spinlock or file I/O)
*
+ * A thread can also be joining a thread (the joiner field above).
+ *
+ * It must not be possible for a thread to belong to any of the
+ * above queues while it is handling a signal. Signal handlers
+ * may longjmp back to previous stack frames circumventing normal
+ * control flow. This could corrupt queue integrity if the thread
+ * retains membership in the queue. Therefore, if a thread is a
+ * member of one of these queues when a signal handler is invoked,
+ * it must remove itself from the queue before calling the signal
+ * handler and reinsert itself after normal return of the handler.
+ *
* Use pqe for the scheduling queue link (both ready and waiting),
- * and qe for other links.
+ * sqe for synchronization (mutex and condition variable) queue
+ * links, and qe for all other links.
*/
- /* Priority queue entry for this thread: */
- pthread_entry_t pqe;
-
- /* Priority queue entry for this thread: */
- pthread_entry_t sqe;
-
- /* Queue entry for this thread: */
- pthread_entry_t qe;
+ pthread_entry_t pqe; /* priority queue link */
+ pthread_entry_t sqe; /* synchronization queue link */
+ pthread_entry_t qe; /* all other queues link */
/* Wait data. */
union pthread_wait_data data;
@@ -704,19 +720,19 @@ struct pthread {
*/
int yield_on_sig_undefer;
- /* Miscellaneous data. */
+ /* Miscellaneous flags; only set with signals deferred. */
int flags;
#define PTHREAD_FLAGS_PRIVATE 0x0001
#define PTHREAD_EXITING 0x0002
-#define PTHREAD_FLAGS_IN_WAITQ 0x0004 /* in waiting queue using pqe link*/
-#define PTHREAD_FLAGS_IN_PRIOQ 0x0008 /* in priority queue using pqe link*/
+#define PTHREAD_FLAGS_IN_WAITQ 0x0004 /* in waiting queue using pqe link */
+#define PTHREAD_FLAGS_IN_PRIOQ 0x0008 /* in priority queue using pqe link */
#define PTHREAD_FLAGS_IN_WORKQ 0x0010 /* in work queue using qe link */
#define PTHREAD_FLAGS_IN_FILEQ 0x0020 /* in file lock queue using qe link */
#define PTHREAD_FLAGS_IN_FDQ 0x0040 /* in fd lock queue using qe link */
-#define PTHREAD_FLAGS_IN_CONDQ 0x0080 /* in condition queue using sqe link*/
-#define PTHREAD_FLAGS_IN_MUTEXQ 0x0100 /* in mutex queue using sqe link*/
+#define PTHREAD_FLAGS_IN_CONDQ 0x0080 /* in condition queue using sqe link */
+#define PTHREAD_FLAGS_IN_MUTEXQ 0x0100 /* in mutex queue using sqe link */
#define PTHREAD_FLAGS_TRACE 0x0200 /* for debugging purposes */
-#define PTHREAD_FLAGS_IN_SYNQ \
+#define PTHREAD_FLAGS_IN_SYNCQ \
(PTHREAD_FLAGS_IN_CONDQ | PTHREAD_FLAGS_IN_MUTEXQ)
/*
@@ -992,6 +1008,21 @@ SCLASS volatile int _spinblock_count
#endif
;
+/* Used to maintain pending and active signals: */
+struct sigstatus {
+ int pending; /* Is this a pending signal? */
+ int blocked; /*
+ * A handler is currently active for
+ * this signal; ignore subsequent
+ * signals until the handler is done.
+ */
+ int signo; /* arg 1 to signal handler */
+ siginfo_t siginfo; /* arg 2 to signal handler */
+ struct sigcontext uc; /* arg 3 to signal handler */
+};
+
+SCLASS struct sigstatus _thread_sigq[NSIG];
+
/* Indicates that the signal queue needs to be checked. */
SCLASS volatile int _sigq_check_reqd
#ifdef GLOBAL_PTHREAD_PRIVATE
@@ -999,6 +1030,9 @@ SCLASS volatile int _sigq_check_reqd
#endif
;
+/* The signal stack. */
+SCLASS struct sigaltstack _thread_sigstack;
+
/* Thread switch hook. */
SCLASS pthread_switch_routine_t _sched_switch_hook
#ifdef GLOBAL_PTHREAD_PRIVATE
diff --git a/lib/libpthread/uthread/uthread_cancel.c b/lib/libpthread/uthread/uthread_cancel.c
index 8c8515dbbc7..29f3a8edebf 100644
--- a/lib/libpthread/uthread/uthread_cancel.c
+++ b/lib/libpthread/uthread/uthread_cancel.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_cancel.c,v 1.8 2001/12/11 00:19:47 fgsch Exp $ */
+/* $OpenBSD: uthread_cancel.c,v 1.9 2001/12/19 02:02:52 fgsch Exp $ */
/*
* David Leonard <d@openbsd.org>, 1999. Public domain.
*/
@@ -59,17 +59,6 @@ pthread_cancel(pthread)
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
break;
- case PS_MUTEX_WAIT:
- case PS_COND_WAIT:
- case PS_FDLR_WAIT:
- case PS_FDLW_WAIT:
- case PS_FILE_WAIT:
- pthread->interrupted = 1;
- pthread->cancelflags |= PTHREAD_CANCEL_NEEDED;
- PTHREAD_NEW_STATE(pthread,PS_RUNNING);
- pthread->continuation = finish_cancellation;
- break;
-
case PS_JOIN:
/*
* Disconnect the thread from the joinee and
@@ -85,9 +74,39 @@ pthread_cancel(pthread)
break;
case PS_SUSPENDED:
- /* Simply wake: */
- /* XXX may be incorrect */
+ if (pthread->suspended == SUSP_NO ||
+ pthread->suspended == SUSP_YES ||
+ pthread->suspended == SUSP_JOIN ||
+ pthread->suspended == SUSP_NOWAIT) {
+ /*
+ * This thread isn't in any scheduling
+ * queues; just change it's state:
+ */
+ pthread->cancelflags |=
+ PTHREAD_CANCELLING;
+ PTHREAD_SET_STATE(pthread, PS_RUNNING);
+ break;
+ }
+ /* FALLTHROUGH */
+ case PS_MUTEX_WAIT:
+ case PS_COND_WAIT:
+ case PS_FDLR_WAIT:
+ case PS_FDLW_WAIT:
+ case PS_FILE_WAIT:
+ /*
+ * Threads in these states may be in queues.
+ * In order to preserve queue integrity, the
+ * cancelled thread must remove itself from the
+ * queue. Mark the thread as interrupted and
+ * needing cancellation, and set the state to
+ * running. When the thread resumes, it will
+ * remove itself from the queue and call the
+ * cancellation completion routine.
+ */
+ pthread->interrupted = 1;
+ pthread->cancelflags |= PTHREAD_CANCEL_NEEDED;
PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ pthread->continuation = finish_cancellation;
break;
case PS_DEAD:
diff --git a/lib/libpthread/uthread/uthread_exit.c b/lib/libpthread/uthread/uthread_exit.c
index 232b55e008e..a7a0c60a267 100644
--- a/lib/libpthread/uthread/uthread_exit.c
+++ b/lib/libpthread/uthread/uthread_exit.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_exit.c,v 1.14 2001/12/11 00:19:47 fgsch Exp $ */
+/* $OpenBSD: uthread_exit.c,v 1.15 2001/12/19 02:02:52 fgsch Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -226,11 +226,9 @@ pthread_exit(void *status)
pthread->join_status.error = 0;
pthread->join_status.thread = NULL;
-#ifdef notyet
/* Make this thread collectable by the garbage collector. */
PTHREAD_ASSERT(((curthread->attr.flags & PTHREAD_DETACHED) ==
0), "Cannot join a detached thread");
-#endif
curthread->attr.flags |= PTHREAD_DETACHED;
}
diff --git a/lib/libpthread/uthread/uthread_join.c b/lib/libpthread/uthread/uthread_join.c
index 1cf1624a884..0167427b570 100644
--- a/lib/libpthread/uthread/uthread_join.c
+++ b/lib/libpthread/uthread/uthread_join.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_join.c,v 1.8 2001/12/11 00:19:47 fgsch Exp $ */
+/* $OpenBSD: uthread_join.c,v 1.9 2001/12/19 02:02:52 fgsch Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -134,7 +134,6 @@ pthread_join(pthread_t pthread, void **thread_return)
* joining to when it exits or detaches:
*/
ret = curthread->join_status.error;
- ret = curthread->join_status.error;
if ((ret == 0) && (thread_return != NULL))
*thread_return = curthread->join_status.ret;
} else {
diff --git a/lib/libpthread/uthread/uthread_resume_np.c b/lib/libpthread/uthread/uthread_resume_np.c
index 8816f76e4c8..ace16df8e45 100644
--- a/lib/libpthread/uthread/uthread_resume_np.c
+++ b/lib/libpthread/uthread/uthread_resume_np.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_resume_np.c,v 1.4 1999/11/25 07:01:42 d Exp $ */
+/* $OpenBSD: uthread_resume_np.c,v 1.5 2001/12/19 02:02:52 fgsch Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -41,20 +41,49 @@
int
pthread_resume_np(pthread_t thread)
{
- int ret;
+ int ret;
+ enum pthread_susp old_suspended;
/* Find the thread in the list of active threads: */
if ((ret = _find_thread(thread)) == 0) {
- /* The thread exists. Is it suspended? */
- if (thread->state != PS_SUSPENDED) {
+ /* Cancel any pending suspensions: */
+ old_suspended = thread->suspended;
+ thread->suspended = SUSP_NO;
+
+ /* Is it currently suspended? */
+ if (thread->state == PS_SUSPENDED) {
/*
* Defer signals to protect the scheduling queues
* from access by the signal handler:
*/
_thread_kern_sig_defer();
- /* Allow the thread to run. */
- PTHREAD_NEW_STATE(thread,PS_RUNNING);
+ switch (old_suspended) {
+ case SUSP_MUTEX_WAIT:
+ /* Set the thread's state back. */
+ PTHREAD_SET_STATE(thread,PS_MUTEX_WAIT);
+ break;
+ case SUSP_COND_WAIT:
+ /* Set the thread's state back. */
+ PTHREAD_SET_STATE(thread,PS_COND_WAIT);
+ break;
+ case SUSP_JOIN:
+ /* Set the thread's state back. */
+ PTHREAD_SET_STATE(thread,PS_JOIN);
+ break;
+ case SUSP_NOWAIT:
+ /* Allow the thread to run. */
+ PTHREAD_SET_STATE(thread,PS_RUNNING);
+ PTHREAD_WAITQ_REMOVE(thread);
+ PTHREAD_PRIOQ_INSERT_TAIL(thread);
+ break;
+ case SUSP_NO:
+ case SUSP_YES:
+ /* Allow the thread to run. */
+ PTHREAD_SET_STATE(thread,PS_RUNNING);
+ PTHREAD_PRIOQ_INSERT_TAIL(thread);
+ break;
+ }
/*
* Undefer and handle pending signals, yielding if