]> granicus.if.org Git - gc/commitdiff
Fix deadlock in GC_suspend_thread when thread is finished
authorIvan Maidanski <ivmai@mail.ru>
Tue, 11 Jul 2017 22:10:42 +0000 (01:10 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 11 Jul 2017 22:51:05 +0000 (01:51 +0300)
(fix commits 62097c359e2bcf)

* pthread_stop_world.c [GC_ENABLE_SUSPEND_THREAD] (GC_suspend_thread):
Do not call RAISE_SIGNAL() and sem_wait() if thread has FINISHED flag
set; do not handle ESRCH error result of RAISE_SIGNAL(); add comment.

pthread_stop_world.c

index 50f93d7fc26a8e77e5542d1c91754920778c121d..7c6e403030b179b45bcbaba602b3c70fbbc7a7a0 100644 (file)
@@ -434,15 +434,15 @@ STATIC void GC_restart_handler(int sig)
         (void)GC_do_blocking(suspend_self_inner, t);
         return;
       }
+      if ((t -> flags & FINISHED) != 0) {
+        /* Terminated but not joined yet. */
+        UNLOCK();
+        return;
+      }
 
       /* TODO: Support GC_retry_signals */
       switch (RAISE_SIGNAL(t, GC_sig_suspend)) {
-      case ESRCH:
-        /* Not really there anymore (terminated but not joined yet).    */
-        /* No need to wait but leave the suspension flag on.            */
-        GC_ASSERT((t -> flags & FINISHED) != 0);
-        UNLOCK();
-        return;
+      /* ESRCH cannot happen as terminated threads are handled above.   */
       case 0:
         break;
       default: