From 116f52abdefd4f58f3fd06209a5cddd1a33d57b5 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Fri, 30 Dec 2022 18:34:12 +0300 Subject: Fix joinable threads shutdown on NaCl (a cherry-pick of commit a6cd81cbd from 'master') GC_nacl_shutdown_gc_thread() should be called (and value of GC_nacl_gc_thread_self should be cleared) on thread termination even for non-detached threads. Thus, GC_nacl_initialize_gc_thread() should be called (and value of GC_nacl_gc_thread_self should be set) additionally if the thread is registered from its destructor. * pthread_support.c [NACL] (GC_delete_thread): Do not call GC_nacl_shutdown_gc_thread() and do not clear GC_nacl_gc_thread_self. * pthread_support.c [NACL] (GC_unregister_my_thread_inner): Call GC_nacl_shutdown_gc_thread() and clear value of GC_nacl_gc_thread_self (after GC_destroy_thread_local). * pthread_support.c [NACL] (GC_register_my_thread): If KNOWN_FINISHED then set GC_nacl_gc_thread_self to me and call GC_nacl_initialize_gc_thread(). --- pthread_support.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/pthread_support.c b/pthread_support.c index 8395f897..1d46b7d1 100644 --- a/pthread_support.c +++ b/pthread_support.c @@ -582,12 +582,6 @@ STATIC void GC_delete_thread(pthread_t id) GC_log_printf("Deleting thread %p, n_threads = %d\n", (void *)id, GC_count_threads()); # endif - -# ifdef NACL - GC_nacl_shutdown_gc_thread(); - GC_nacl_gc_thread_self = NULL; -# endif - GC_ASSERT(I_HOLD_LOCK()); while (!THREAD_EQUAL(p -> id, id)) { prev = p; @@ -1600,6 +1594,10 @@ STATIC void GC_unregister_my_thread_inner(GC_thread me) GC_ASSERT(GC_getspecific(GC_thread_key) == &me->tlfs); GC_destroy_thread_local(&(me->tlfs)); # endif +# ifdef NACL + GC_nacl_shutdown_gc_thread(); + GC_nacl_gc_thread_self = NULL; +# endif # if defined(GC_HAVE_PTHREAD_EXIT) || !defined(GC_NO_PTHREAD_CANCEL) /* Handle DISABLED_GC flag which is set by the */ /* intercepted pthread_cancel or pthread_exit. */ @@ -1860,6 +1858,10 @@ 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. */ +# ifdef NACL + GC_nacl_gc_thread_self = me; + GC_nacl_initialize_gc_thread(); +# endif # ifdef GC_DARWIN_THREADS /* Reinitialize mach_thread to avoid thread_suspend fail */ /* with MACH_SEND_INVALID_DEST error. */ -- cgit v1.2.1