diff options
author | Andy Wingo <wingo@pobox.com> | 2016-11-14 21:25:53 +0100 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2016-11-14 21:25:53 +0100 |
commit | e447258c3f204de22c221ec153850db052acc437 (patch) | |
tree | ea74c4f827e113000bbcd5929d23c14d8de99244 | |
parent | 3f23688f397722546861d04688c3eefb0c9c9149 (diff) | |
download | guile-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.c | 78 | ||||
-rw-r--r-- | libguile/throw.c | 22 | ||||
-rw-r--r-- | libguile/throw.h | 5 |
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, |