summaryrefslogtreecommitdiffstats
path: root/lib/libthr
diff options
context:
space:
mode:
authormtm <mtm@FreeBSD.org>2003-06-02 11:01:00 +0000
committermtm <mtm@FreeBSD.org>2003-06-02 11:01:00 +0000
commit66c0bae29f7f72f4b60c8711040b9cb0592bc5b2 (patch)
tree02ccb425c444f24ab69b025f164048f132d29a37 /lib/libthr
parente96dba4eaa0223c5a85363f6a1532bc3d7f7f7eb (diff)
downloadFreeBSD-src-66c0bae29f7f72f4b60c8711040b9cb0592bc5b2.zip
FreeBSD-src-66c0bae29f7f72f4b60c8711040b9cb0592bc5b2.tar.gz
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.
Diffstat (limited to 'lib/libthr')
-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 b11728e..23e985f 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);
}
OpenPOWER on IntegriCloud