guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] 01/01: Fix support for threads already known to GC


From: Andy Wingo
Subject: [Guile-commits] 01/01: Fix support for threads already known to GC
Date: Tue, 28 Feb 2017 07:16:19 -0500 (EST)

wingo pushed a commit to branch master
in repository guile.

commit 4c3bea3dba345567c3689bf4ba68a85f6209eb17
Author: Andy Wingo <address@hidden>
Date:   Tue Feb 28 13:14:02 2017 +0100

    Fix support for threads already known to GC
    
    * libguile/threads.h (scm_i_thread): Add bool tracking whether the
      thread needs to be unregistered from libgc.
    * libguile/threads.c (guilify_self_1): Add needs_unregister arg.
      (on_thread_exit): Only unregister thread if the thread needs it.
      (scm_i_init_thread_for_guile): A thread needs unregistering if
      GC_register_my_thread succeeded.
      (scm_threads_prehistory): Don't unregister initial thread.
    
      Fixes #19523.  Thanks to Anthonin Bonnefoy for the report.
---
 libguile/threads.c | 19 ++++++++++++++-----
 libguile/threads.h |  3 +++
 2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/libguile/threads.c b/libguile/threads.c
index 1faa539..e67616c 100644
--- a/libguile/threads.c
+++ b/libguile/threads.c
@@ -372,7 +372,7 @@ static SCM default_dynamic_state;
 /* Perform first stage of thread initialisation, in non-guile mode.
  */
 static void
-guilify_self_1 (struct GC_stack_base *base)
+guilify_self_1 (struct GC_stack_base *base, int needs_unregister)
 {
   scm_i_thread t;
 
@@ -410,6 +410,7 @@ guilify_self_1 (struct GC_stack_base *base)
 
   t.exited = 0;
   t.guile_mode = 0;
+  t.needs_unregister = needs_unregister;
 
   /* The switcheroo.  */
   {
@@ -523,8 +524,13 @@ on_thread_exit (void *v)
       scm_i_vm_free_stack (vp);
   }
 
+#ifdef SCM_HAVE_THREAD_STORAGE_CLASS
+  scm_i_current_thread = NULL;
+#endif
+
 #if SCM_USE_PTHREAD_THREADS
-  GC_unregister_my_thread ();
+  if (t->needs_unregister)
+    GC_unregister_my_thread ();
 #endif
 }
 
@@ -586,6 +592,8 @@ scm_i_init_thread_for_guile (struct GC_stack_base *base,
        }
       else
        {
+          int needs_unregister = 0;
+
          /* Guile is already initialized, but this thread enters it for
             the first time.  Only initialize this thread.
          */
@@ -593,10 +601,11 @@ scm_i_init_thread_for_guile (struct GC_stack_base *base,
 
           /* Register this thread with libgc.  */
 #if SCM_USE_PTHREAD_THREADS
-          GC_register_my_thread (base);
+          if (GC_register_my_thread (base) == GC_SUCCESS)
+            needs_unregister = 1;
 #endif
 
-         guilify_self_1 (base);
+         guilify_self_1 (base, needs_unregister);
          guilify_self_2 (dynamic_state);
        }
       return 1;
@@ -1782,7 +1791,7 @@ scm_threads_prehistory (void *base)
                 GC_MAKE_PROC (GC_new_proc (thread_mark), 0),
                 0, 1);
 
-  guilify_self_1 ((struct GC_stack_base *) base);
+  guilify_self_1 ((struct GC_stack_base *) base, 0);
 }
 
 scm_t_bits scm_tc16_thread;
diff --git a/libguile/threads.h b/libguile/threads.h
index 645e5eb..55c566d 100644
--- a/libguile/threads.h
+++ b/libguile/threads.h
@@ -59,6 +59,9 @@ typedef struct scm_i_thread {
 
   /* Boolean indicating whether the thread is in guile mode.  */
   int guile_mode;
+  /* Boolean indicating whether to call GC_unregister_my_thread () when
+     this thread exits.  */
+  int needs_unregister;
 
   struct scm_thread_wake_data *wake;
   scm_i_pthread_cond_t sleep_cond;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]