summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2016-11-14 21:25:53 +0100
committerAndy Wingo <wingo@pobox.com>2016-11-14 21:25:53 +0100
commite447258c3f204de22c221ec153850db052acc437 (patch)
treeea74c4f827e113000bbcd5929d23c14d8de99244
parent3f23688f397722546861d04688c3eefb0c9c9149 (diff)
downloadguile-e447258c3f204de22c221ec153850db052acc437.tar.gz
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.
-rw-r--r--libguile/threads.c78
-rw-r--r--libguile/throw.c22
-rw-r--r--libguile/throw.h5
3 files changed, 22 insertions, 83 deletions
diff --git a/libguile/threads.c b/libguile/threads.c
index 262e2ed9d..97320571b 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 38fe149fa..45bab7a70 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 e2da73170..f2020a331 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,