From c651715cd32958d6c6efe3800eb15f6667d4784f Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Tue, 21 Jun 2016 09:48:21 +0300 Subject: Fix GC_suspend_thread for terminated threads * pthread_stop_world.c (GC_suspend_thread): Do not clear SUSPENDED_EXT flag in case of RAISE_SIGNAL() failure, add assertion about FINISHED (in case of ESRCH), update comment. * pthread_stop_world.c (GC_register_my_thread): Add assertion that SUSPENDED_EXT flag is not set if the thread is registered from a thread key destructor. --- pthread_stop_world.c | 5 +++-- pthread_support.c | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pthread_stop_world.c b/pthread_stop_world.c index 244731e4..1ee9ee8f 100644 --- a/pthread_stop_world.c +++ b/pthread_stop_world.c @@ -433,8 +433,9 @@ STATIC void GC_restart_handler(int sig) /* TODO: Support GC_retry_signals */ switch (RAISE_SIGNAL(t, GC_sig_suspend)) { case ESRCH: - /* Not really there anymore. Possible? */ - t -> flags &= ~SUSPENDED_EXT; + /* 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; case 0: diff --git a/pthread_support.c b/pthread_support.c index d9f935f7..d0c9cb10 100644 --- a/pthread_support.c +++ b/pthread_support.c @@ -1617,6 +1617,7 @@ GC_API int GC_CALL GC_register_my_thread(const struct GC_stack_base *sb) } else if ((me -> flags & FINISHED) != 0) { /* This code is executed when a thread is registered from the */ /* client thread key destructor. */ + GC_ASSERT((me -> flags & SUSPENDED_EXT) == 0); GC_record_stack_base(me, sb); me -> flags &= ~FINISHED; /* but not DETACHED */ # ifdef GC_EXPLICIT_SIGNALS_UNBLOCK -- cgit v1.2.1