Skip to content

Commit

Permalink
Prevent multiple sem_post calls for a thread in suspend_handler
Browse files Browse the repository at this point in the history
(fix commit af409e4)

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.
  • Loading branch information
ivmai committed Dec 28, 2017
1 parent 62d2d77 commit ff5a875
Showing 1 changed file with 8 additions and 7 deletions.
15 changes: 8 additions & 7 deletions pthread_stop_world.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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). */
Expand Down

0 comments on commit ff5a875

Please sign in to comment.