aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMike Makonnen <mtm@FreeBSD.org>2003-06-02 11:01:00 +0000
committerMike Makonnen <mtm@FreeBSD.org>2003-06-02 11:01:00 +0000
commitcff6c3cab1af1d424484233d765f2f4095e90e64 (patch)
tree02ccb425c444f24ab69b025f164048f132d29a37 /lib
parent438441203054e5eeb67f8cd8ca4eb0ef1603bc81 (diff)
downloadsrc-cff6c3cab1af1d424484233d765f2f4095e90e64.tar.gz
src-cff6c3cab1af1d424484233d765f2f4095e90e64.zip
Unwind the _giant_mutex from pthread_detach(). When detaching a joiner thread
it's important the correct lock order is observed: lock first the joined and then the joiner.
Notes
Notes: svn path=/head/; revision=115693
Diffstat (limited to 'lib')
-rw-r--r--lib/libthr/thread/thr_detach.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/lib/libthr/thread/thr_detach.c b/lib/libthr/thread/thr_detach.c
index b11728e44c23..23e985f72f4b 100644
--- a/lib/libthr/thread/thr_detach.c
+++ b/lib/libthr/thread/thr_detach.c
@@ -44,20 +44,19 @@ _pthread_detach(pthread_t pthread)
if (pthread == NULL || pthread->magic != PTHREAD_MAGIC)
return (EINVAL);
- if (pthread->attr.flags & PTHREAD_DETACHED)
+ _SPINLOCK(&pthread->lock);
+
+ if (pthread->attr.flags & PTHREAD_DETACHED) {
+ _SPINUNLOCK(&pthread->lock);
return (EINVAL);
+ }
pthread->attr.flags |= PTHREAD_DETACHED;
- /*
- * Defer signals to protect the scheduling queues from
- * access by the signal handler:
- */
- GIANT_LOCK(curthread);
-
/* Check if there is a joiner: */
if (pthread->joiner != NULL) {
struct pthread *joiner = pthread->joiner;
+ _thread_critical_enter(joiner);
/* Make the thread runnable: */
PTHREAD_NEW_STATE(joiner, PS_RUNNING);
@@ -71,9 +70,10 @@ _pthread_detach(pthread_t pthread)
* Disconnect the joiner from the thread being detached:
*/
pthread->joiner = NULL;
+ _thread_critical_exit(joiner);
}
- GIANT_UNLOCK(curthread);
+ _SPINUNLOCK(&pthread->lock);
return (0);
}