guile-commits
[Top][All Lists]
Advanced

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

[Guile-commits] 01/03: scm_spawn_thread uses call-with-new-thread


From: Andy Wingo
Subject: [Guile-commits] 01/03: scm_spawn_thread uses call-with-new-thread
Date: Mon, 14 Nov 2016 21:02:39 +0000 (UTC)

wingo pushed a commit to branch master
in repository guile.

commit e447258c3f204de22c221ec153850db052acc437
Author: Andy Wingo <address@hidden>
Date:   Mon Nov 14 21:25:53 2016 +0100

    scm_spawn_thread uses call-with-new-thread
    
    * libguile/throw.h (scm_i_make_catch_body_closure)
      (scm_i_make_catch_handler_closure): Add scm_i_ prefix and make
      available for internal use.
    * libguile/throw.c: Adapt.
    * libguile/threads.c (scm_spawn_thread): Rewrite in terms of
      scm_call_with_new_thread.
---
 libguile/threads.c |   78 ++++------------------------------------------------
 libguile/throw.c   |   22 ++++++++-------
 libguile/throw.h   |    5 ++++
 3 files changed, 22 insertions(+), 83 deletions(-)

diff --git a/libguile/threads.c b/libguile/threads.c
index 262e2ed..9732057 100644
--- a/libguile/threads.c
+++ b/libguile/threads.c
@@ -845,85 +845,17 @@ SCM_DEFINE (scm_sys_call_with_new_thread, 
"%call-with-new-thread", 1, 0, 0,
 }
 #undef FUNC_NAME
 
-typedef struct {
-  SCM parent;
-  scm_t_catch_body body;
-  void *body_data;
-  scm_t_catch_handler handler;
-  void *handler_data;
-  SCM thread;
-  scm_i_pthread_mutex_t mutex;
-  scm_i_pthread_cond_t cond;
-} spawn_data;
-
-static void *
-really_spawn (void *d)
-{
-  spawn_data *data = (spawn_data *)d;
-  scm_t_catch_body body = data->body;
-  void *body_data = data->body_data;
-  scm_t_catch_handler handler = data->handler;
-  void *handler_data = data->handler_data;
-  scm_i_thread *t = SCM_I_CURRENT_THREAD;
-
-  scm_i_scm_pthread_mutex_lock (&data->mutex);
-  data->thread = scm_current_thread ();
-  scm_i_pthread_cond_signal (&data->cond);
-  scm_i_pthread_mutex_unlock (&data->mutex);
-
-  if (handler == NULL)
-    t->result = body (body_data);
-  else
-    t->result = scm_internal_catch (SCM_BOOL_T,
-                                   body, body_data,
-                                   handler, handler_data);
-
-  return 0;
-}
-
-static void *
-spawn_thread (void *d)
-{
-  spawn_data *data = (spawn_data *)d;
-  scm_i_pthread_detach (scm_i_pthread_self ());
-  scm_i_with_guile_and_parent (really_spawn, d, data->parent);
-  return NULL;
-}
-
 SCM
 scm_spawn_thread (scm_t_catch_body body, void *body_data,
                  scm_t_catch_handler handler, void *handler_data)
 {
-  spawn_data data;
-  scm_i_pthread_t id;
-  int err;
-
-  data.parent = scm_current_dynamic_state ();
-  data.body = body;
-  data.body_data = body_data;
-  data.handler = handler;
-  data.handler_data = handler_data;
-  data.thread = SCM_BOOL_F;
-  scm_i_pthread_mutex_init (&data.mutex, NULL);
-  scm_i_pthread_cond_init (&data.cond, NULL);
-
-  scm_i_scm_pthread_mutex_lock (&data.mutex);
-  err = scm_i_pthread_create (&id, NULL, spawn_thread, &data);
-  if (err)
-    {
-      scm_i_pthread_mutex_unlock (&data.mutex);
-      errno = err;
-      scm_syserror (NULL);
-    }
-
-  while (scm_is_false (data.thread))
-    scm_i_scm_pthread_cond_wait (&data.cond, &data.mutex);
-
-  scm_i_pthread_mutex_unlock (&data.mutex);
+  SCM body_closure, handler_closure;
 
-  assert (SCM_I_IS_THREAD (data.thread));
+  body_closure = scm_i_make_catch_body_closure (body, body_data);
+  handler_closure = handler == NULL ? SCM_UNDEFINED :
+    scm_i_make_catch_handler_closure (handler, handler_data);
 
-  return data.thread;
+  return scm_call_with_new_thread (body_closure, handler_closure);
 }
 
 SCM_DEFINE (scm_yield, "yield", 0, 0, 0,
diff --git a/libguile/throw.c b/libguile/throw.c
index 38fe149..45bab7a 100644
--- a/libguile/throw.c
+++ b/libguile/throw.c
@@ -272,8 +272,8 @@ enum {
   CATCH_CLOSURE_HANDLER
 };
 
-static SCM
-make_catch_body_closure (scm_t_catch_body body, void *body_data)
+SCM
+scm_i_make_catch_body_closure (scm_t_catch_body body, void *body_data)
 {
   SCM ret;
   SCM_NEWSMOB2 (ret, tc16_catch_closure, body, body_data);
@@ -281,8 +281,9 @@ make_catch_body_closure (scm_t_catch_body body, void 
*body_data)
   return ret;
 }
 
-static SCM
-make_catch_handler_closure (scm_t_catch_handler handler, void *handler_data)
+SCM
+scm_i_make_catch_handler_closure (scm_t_catch_handler handler,
+                                  void *handler_data)
 {
   SCM ret;
   SCM_NEWSMOB2 (ret, tc16_catch_closure, handler, handler_data);
@@ -359,11 +360,12 @@ scm_c_catch (SCM tag,
 {
   SCM sbody, shandler, spre_unwind_handler;
   
-  sbody = make_catch_body_closure (body, body_data);
-  shandler = make_catch_handler_closure (handler, handler_data);
+  sbody = scm_i_make_catch_body_closure (body, body_data);
+  shandler = scm_i_make_catch_handler_closure (handler, handler_data);
   if (pre_unwind_handler)
-    spre_unwind_handler = make_catch_handler_closure (pre_unwind_handler,
-                                                      pre_unwind_handler_data);
+    spre_unwind_handler =
+      scm_i_make_catch_handler_closure (pre_unwind_handler,
+                                        pre_unwind_handler_data);
   else
     spre_unwind_handler = SCM_UNDEFINED;
   
@@ -403,8 +405,8 @@ scm_c_with_throw_handler (SCM tag,
        "and adapt it (if necessary) to expect to be within the dynamic 
context\n"
        "of the throw.");
 
-  sbody = make_catch_body_closure (body, body_data);
-  shandler = make_catch_handler_closure (handler, handler_data);
+  sbody = scm_i_make_catch_body_closure (body, body_data);
+  shandler = scm_i_make_catch_handler_closure (handler, handler_data);
   
   return scm_with_throw_handler (tag, sbody, shandler);
 }
diff --git a/libguile/throw.h b/libguile/throw.h
index e2da731..f2020a3 100644
--- a/libguile/throw.h
+++ b/libguile/throw.h
@@ -31,6 +31,11 @@ typedef SCM (*scm_t_catch_body) (void *data);
 typedef SCM (*scm_t_catch_handler) (void *data,
                                     SCM tag, SCM throw_args);
 
+SCM_INTERNAL SCM scm_i_make_catch_body_closure (scm_t_catch_body body,
+                                                void *body_data);
+SCM_INTERNAL SCM scm_i_make_catch_handler_closure (scm_t_catch_handler h,
+                                                   void *handler_data);
+
 SCM_API SCM scm_c_catch (SCM tag,
                         scm_t_catch_body body,
                         void *body_data,



reply via email to

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