summaryrefslogtreecommitdiff
path: root/pthread_stop_world.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2017-12-28 11:37:57 +0300
committerIvan Maidanski <ivmai@mail.ru>2017-12-28 11:37:57 +0300
commitff5a875bb4ceeffce412a08403dca84ba0a81840 (patch)
tree957e622836a30007afdf033e970ccbe874ec6cac /pthread_stop_world.c
parent62d2d77df3e8da9760f82e327ee95ded94075073 (diff)
downloadbdwgc-ff5a875bb4ceeffce412a08403dca84ba0a81840.tar.gz
Prevent multiple sem_post calls for a thread in suspend_handler
(fix commit af409e4bd) Issue #181 (bdwgc). * pthread_stop_world.c [!GC_OPENBSD_UTHREADS && !NACL && THREAD_SANITIZER] (GC_suspend_handler_inner): Call pthread_sigmask() after last_stop_count update (thus preventing duplicate sem_post() call in case of GC_suspend_handler_inner is re-entered (if GC_retry_signals); refine comment.
Diffstat (limited to 'pthread_stop_world.c')
-rw-r--r--pthread_stop_world.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/pthread_stop_world.c b/pthread_stop_world.c
index bda842c7..5188cdc8 100644
--- a/pthread_stop_world.c
+++ b/pthread_stop_world.c
@@ -333,8 +333,15 @@ STATIC void GC_suspend_handler_inner(ptr_t dummy GC_ATTR_UNUSED,
}
GC_store_stack_ptr(me);
+ /* Tell the thread that wants to stop the world that this */
+ /* thread has been stopped. Note that sem_post() is */
+ /* the only async-signal-safe primitive in LinuxThreads. */
+ sem_post(&GC_suspend_ack_sem);
+ AO_store_release(&me->stop_info.last_stop_count, my_stop_count);
+
# ifdef THREAD_SANITIZER
- /* TSan disables signals around signal handlers. */
+ /* TSan disables signals around signal handlers. Without */
+ /* a pthread_sigmask call, sigsuspend may block forever. */
{
sigset_t set;
sigemptyset(&set);
@@ -343,12 +350,6 @@ STATIC void GC_suspend_handler_inner(ptr_t dummy GC_ATTR_UNUSED,
}
# endif
- /* Tell the thread that wants to stop the world that this */
- /* thread has been stopped. Note that sem_post() is */
- /* the only async-signal-safe primitive in LinuxThreads. */
- sem_post(&GC_suspend_ack_sem);
- AO_store_release(&me->stop_info.last_stop_count, my_stop_count);
-
/* Wait until that thread tells us to restart by sending */
/* this thread a GC_sig_thr_restart signal (should be masked */
/* at this point thus there is no race). */