diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2017-12-28 11:37:57 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2017-12-28 11:37:57 +0300 |
commit | ff5a875bb4ceeffce412a08403dca84ba0a81840 (patch) | |
tree | 957e622836a30007afdf033e970ccbe874ec6cac /pthread_stop_world.c | |
parent | 62d2d77df3e8da9760f82e327ee95ded94075073 (diff) | |
download | bdwgc-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.c | 15 |
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). */ |