summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2022-12-30 18:34:12 +0300
committerIvan Maidanski <ivmai@mail.ru>2023-03-14 11:36:52 +0300
commit116f52abdefd4f58f3fd06209a5cddd1a33d57b5 (patch)
tree80e9c429575e18453c49146c1909e55f8cfe072c
parent0519265b7aac7e57a012611b7f7a80eb2bfd1e55 (diff)
downloadbdwgc-116f52abdefd4f58f3fd06209a5cddd1a33d57b5.tar.gz
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().
-rw-r--r--pthread_support.c14
1 files 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. */