From: Ivan Maidanski Date: Thu, 28 Dec 2017 08:37:57 +0000 (+0300) Subject: Prevent multiple sem_post calls for a thread in suspend_handler X-Git-Tag: v8.0.0~433 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ff5a875bb4ceeffce412a08403dca84ba0a81840;p=platform%2Fupstream%2Flibgc.git 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. --- diff --git a/pthread_stop_world.c b/pthread_stop_world.c index bda842c..5188cdc 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). */