]> granicus.if.org Git - gc/commitdiff
Fix data race in last_stop_count access (suspend_handler_inner)
authorIvan Maidanski <ivmai@mail.ru>
Thu, 23 Nov 2017 17:15:54 +0000 (20:15 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Mon, 18 Dec 2017 22:11:27 +0000 (01:11 +0300)
(Cherry-pick commit 7de43fef from 'release-7_4' branch.)

* include/private/pthread_stop_world.h [!GC_OPENBSD_THREADS]
(thread_stop_info.last_stop_count): Change the
type from word to AO_t; add volatile qualifier; fix a typo in comment
("GC_stop_count").
* pthread_stop_world.c [!GC_OPENBSD_THREADS && !NACL]
(GC_suspend_handler_inner): Replace
me->stop_info.last_stop_count=my_stop_count with
AO_store_release(&me->stop_info.last_stop_count,my_stop_count).

include/private/pthread_stop_world.h
pthread_stop_world.c

index cb67d230b3869a697581c5c090c7f03d2b7adeff..17921f0b994f3bde2507200b11424491ed83cad2 100644 (file)
@@ -20,9 +20,9 @@
 
 struct thread_stop_info {
 #   ifndef GC_OPENBSD_THREADS
-      word last_stop_count;     /* GC_last_stop_count value when thread */
-                                /* last successfully handled a suspend  */
-                                /* signal.                              */
+      volatile AO_t last_stop_count;
+                        /* The value of GC_stop_count when the thread   */
+                        /* last successfully handled a suspend signal.  */
 #   endif
 
     ptr_t stack_ptr;            /* Valid only when stopped.             */
index 0ca021288752d9c44779afd729431759bbada431..09b88a86e0baeb31832408cb0e0c3d9460d6156e 100644 (file)
@@ -244,7 +244,7 @@ STATIC void GC_suspend_handler_inner(ptr_t sig_arg, void *context)
   /* thread has been stopped.  Note that sem_post() is          */
   /* the only async-signal-safe primitive in LinuxThreads.      */
   sem_post(&GC_suspend_ack_sem);
-  me -> stop_info.last_stop_count = my_stop_count;
+  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 SIG_THR_RESTART signal.                      */