1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-20 11:40:18 +02:00

Implement scm_without_guile ()' in terms of GC_do_blocking ()'.

* libguile/threads.c (guilify_self_1): Initialize `t->guile_mode'.
  (guilify_self_2): Likewise.
  (struct without_guile_arg): New type.
  (without_guile_trampoline): New function.
  (scm_without_guile): Implement in terms of `GC_do_blocking ()'.

* libguile/threads.h (scm_i_thread)[guile_mode]: New field.
This commit is contained in:
Ludovic Courtès 2008-09-18 22:55:16 +02:00
parent 108e4c5b64
commit 72e6b60838
2 changed files with 56 additions and 6 deletions

View file

@ -457,6 +457,7 @@ guilify_self_1 (SCM_STACKITEM *base)
t->current_mark_stack_limit = NULL;
t->canceled = 0;
t->exited = 0;
t->guile_mode = 0;
scm_i_pthread_setspecific (scm_i_thread_key, t);
@ -474,6 +475,8 @@ guilify_self_2 (SCM parent)
{
scm_i_thread *t = SCM_I_CURRENT_THREAD;
t->guile_mode = 1;
SCM_NEWSMOB (t->handle, scm_tc16_thread, t);
t->continuation_root = scm_cons (t->handle, SCM_EOL);
@ -797,17 +800,61 @@ scm_i_with_guile_and_parent (void *(*func)(void *), void *data, SCM parent)
return res;
}
/*** Non-guile mode. */
#if (defined HAVE_GC_DO_BLOCKING) && (!defined HAVE_DECL_GC_DO_BLOCKING)
/* This declaration is missing from the public headers of GC 7.1. */
extern void GC_do_blocking (void (*) (void *), void *);
#endif
#ifdef HAVE_GC_DO_BLOCKING
struct without_guile_arg
{
void * (*function) (void *);
void *data;
void *result;
};
static void
without_guile_trampoline (void *closure)
{
struct without_guile_arg *arg;
SCM_I_CURRENT_THREAD->guile_mode = 0;
arg = (struct without_guile_arg *) closure;
arg->result = arg->function (arg->data);
SCM_I_CURRENT_THREAD->guile_mode = 1;
}
#endif
void *
scm_without_guile (void *(*func)(void *), void *data)
{
void *res;
scm_t_guile_ticket t;
t = scm_leave_guile ();
res = func (data);
scm_enter_guile (t);
return res;
void *result;
#ifdef HAVE_GC_DO_BLOCKING
if (SCM_I_CURRENT_THREAD->guile_mode)
{
struct without_guile_arg arg;
arg.function = func;
arg.data = data;
GC_do_blocking (without_guile_trampoline, &arg);
result = arg.result;
}
else
#endif
result = func (data);
return result;
}
/*** Thread creation */
typedef struct {

View file

@ -61,6 +61,9 @@ typedef struct scm_i_thread {
int canceled;
int exited;
/* Boolean indicating whether the thread is in guile mode. */
int guile_mode;
SCM sleep_object;
scm_i_pthread_mutex_t *sleep_mutex;
scm_i_pthread_cond_t sleep_cond;