diff options
author | mtm <mtm@FreeBSD.org> | 2003-06-02 11:01:00 +0000 |
---|---|---|
committer | mtm <mtm@FreeBSD.org> | 2003-06-02 11:01:00 +0000 |
commit | 66c0bae29f7f72f4b60c8711040b9cb0592bc5b2 (patch) | |
tree | 02ccb425c444f24ab69b025f164048f132d29a37 /lib/libthr | |
parent | e96dba4eaa0223c5a85363f6a1532bc3d7f7f7eb (diff) | |
download | FreeBSD-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.c | 16 |
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); } |