guile-commits
[Top][All Lists]
Advanced

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

[Guile-commits] 01/01: Protect call-with-new-thread data from GC.


From: Andy Wingo
Subject: [Guile-commits] 01/01: Protect call-with-new-thread data from GC.
Date: Wed, 11 Jan 2017 21:19:46 +0000 (UTC)

wingo pushed a commit to branch master
in repository guile.

commit 63bf6ffa0d3cdddf8151cc80ac18fe5dfb614587
Author: Andy Wingo <address@hidden>
Date:   Wed Jan 11 22:17:24 2017 +0100

    Protect call-with-new-thread data from GC.
    
    * libguile/threads.c (struct launch_data): Add prev/next pointers.
      (protected_launch_data, protected_launch_data_lock): New static vars.
      (protect_launch_data, unprotect_launch_data): New functions.
      (really_launch, scm_sys_call_with_new_thread): Preserve launch data
      from GC.  Thanks to Linas Vepstas for the report!
---
 libguile/threads.c |   39 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 37 insertions(+), 2 deletions(-)

diff --git a/libguile/threads.c b/libguile/threads.c
index da5b814..1faa539 100644
--- a/libguile/threads.c
+++ b/libguile/threads.c
@@ -735,15 +735,49 @@ scm_call_with_new_thread (SCM thunk, SCM handler)
   return scm_call_2 (call_with_new_thread, thunk, handler);
 }
 
-typedef struct {
+typedef struct launch_data launch_data;
+
+struct launch_data {
+  launch_data *prev;
+  launch_data *next;
   SCM dynamic_state;
   SCM thunk;
-} launch_data;
+};
+
+/* GC-protect the launch data for new threads.  */
+static launch_data *protected_launch_data;
+static scm_i_pthread_mutex_t protected_launch_data_lock =
+  SCM_I_PTHREAD_MUTEX_INITIALIZER;
+
+static void
+protect_launch_data (launch_data *data)
+{
+  scm_i_pthread_mutex_lock (&protected_launch_data_lock);
+  data->next = protected_launch_data;
+  if (protected_launch_data)
+    protected_launch_data->prev = data;
+  protected_launch_data = data;
+  scm_i_pthread_mutex_unlock (&protected_launch_data_lock);
+}
+
+static void
+unprotect_launch_data (launch_data *data)
+{
+  scm_i_pthread_mutex_lock (&protected_launch_data_lock);
+  if (data->next)
+    data->next->prev = data->prev;
+  if (data->prev)
+    data->prev->next = data->next;
+  else
+    protected_launch_data = data->next;
+  scm_i_pthread_mutex_unlock (&protected_launch_data_lock);
+}
 
 static void *
 really_launch (void *d)
 {
   scm_i_thread *t = SCM_I_CURRENT_THREAD;
+  unprotect_launch_data (d);
   /* The thread starts with asyncs blocked.  */
   t->block_asyncs++;
   SCM_I_CURRENT_THREAD->result = scm_call_0 (((launch_data *)d)->thunk);
@@ -774,6 +808,7 @@ SCM_DEFINE (scm_sys_call_with_new_thread, 
"%call-with-new-thread", 1, 0, 0,
   data = scm_gc_typed_calloc (launch_data);
   data->dynamic_state = scm_current_dynamic_state ();
   data->thunk = thunk;
+  protect_launch_data (data);
   err = scm_i_pthread_create (&id, NULL, launch_thread, data);
   if (err)
     {



reply via email to

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