diff options
author | davidxu <davidxu@FreeBSD.org> | 2012-08-27 03:09:39 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2012-08-27 03:09:39 +0000 |
commit | f83ff5dc9510433a6364807b123ff7b12553b700 (patch) | |
tree | 78d4f5cc3fff1e4d2c5e52fdaed125e71eba4728 /lib/libthr/thread/thr_init.c | |
parent | 9923bbac4d74cc168bd24afba5fdd61803639d2f (diff) | |
download | FreeBSD-src-f83ff5dc9510433a6364807b123ff7b12553b700.zip FreeBSD-src-f83ff5dc9510433a6364807b123ff7b12553b700.tar.gz |
In suspend_common(), don't wait for a thread which is in creation, because
pthread_suspend_all_np() may have already suspended its parent thread.
Add locking code in pthread_suspend_all_np() to only allow one thread
to suspend other threads, this eliminates a deadlock where two or more
threads try to suspend each others.
Diffstat (limited to 'lib/libthr/thread/thr_init.c')
-rw-r--r-- | lib/libthr/thread/thr_init.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/lib/libthr/thread/thr_init.c b/lib/libthr/thread/thr_init.c index e1e304a..c29e8c3 100644 --- a/lib/libthr/thread/thr_init.c +++ b/lib/libthr/thread/thr_init.c @@ -120,6 +120,10 @@ struct umutex _rwlock_static_lock = DEFAULT_UMUTEX; struct umutex _keytable_lock = DEFAULT_UMUTEX; struct urwlock _thr_list_lock = DEFAULT_URWLOCK; struct umutex _thr_event_lock = DEFAULT_UMUTEX; +struct umutex _suspend_all_lock = DEFAULT_UMUTEX; +struct pthread *_single_thread; +int _suspend_all_cycle; +int _suspend_all_waiters; int __pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *); int __pthread_mutex_lock(pthread_mutex_t *); @@ -441,11 +445,14 @@ init_private(void) _thr_umutex_init(&_keytable_lock); _thr_urwlock_init(&_thr_atfork_lock); _thr_umutex_init(&_thr_event_lock); + _thr_umutex_init(&_suspend_all_lock); _thr_once_init(); _thr_spinlock_init(); _thr_list_init(); _thr_wake_addr_init(); _sleepq_init(); + _single_thread = NULL; + _suspend_all_waiters = 0; /* * Avoid reinitializing some things if they don't need to be, |