mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-10 14:00:21 +02:00
pre-GC_set_start_callback compatibility
* configure.ac: Add a check for GC_set_start_callback. * libguile/gc.c (scm_i_gc): If we don't have GC_set_start_callback, run the before-gc hook manually here. (scm_init_gc): Otherwise set it as a start callback. * libguile/hashtab.c (weak_gc_callback, weak_gc_hook) (weak_gc_finalizer, scm_c_register_weak_gc_callback): Fix to work either way, with or without GC_set_start_callback.
This commit is contained in:
parent
631e49ed76
commit
66b229d56e
3 changed files with 38 additions and 9 deletions
|
@ -1238,7 +1238,7 @@ save_LIBS="$LIBS"
|
|||
LIBS="$BDW_GC_LIBS $LIBS"
|
||||
CFLAGS="$BDW_GC_CFLAGS $CFLAGS"
|
||||
|
||||
AC_CHECK_FUNCS([GC_do_blocking GC_call_with_gc_active GC_pthread_exit GC_pthread_cancel GC_allow_register_threads GC_pthread_sigmask])
|
||||
AC_CHECK_FUNCS([GC_do_blocking GC_call_with_gc_active GC_pthread_exit GC_pthread_cancel GC_allow_register_threads GC_pthread_sigmask GC_set_start_callback])
|
||||
|
||||
# Though the `GC_do_blocking ()' symbol is present in GC 7.1, it is not
|
||||
# declared, and has a different type (returning void instead of
|
||||
|
|
|
@ -355,6 +355,9 @@ SCM_DEFINE (scm_gc, "gc", 0, 0, 0,
|
|||
void
|
||||
scm_i_gc (const char *what)
|
||||
{
|
||||
#ifndef HAVE_GC_SET_START_CALLBACK
|
||||
run_before_gc_c_hook ();
|
||||
#endif
|
||||
GC_gcollect ();
|
||||
}
|
||||
|
||||
|
@ -799,7 +802,10 @@ scm_init_gc ()
|
|||
SCM_BOOL_F);
|
||||
|
||||
scm_c_hook_add (&scm_before_gc_c_hook, queue_after_gc_hook, NULL, 0);
|
||||
|
||||
#ifdef HAVE_GC_SET_START_CALLBACK
|
||||
GC_set_start_callback (run_before_gc_c_hook);
|
||||
#endif
|
||||
|
||||
#include "libguile/gc.x"
|
||||
}
|
||||
|
|
|
@ -418,20 +418,39 @@ SCM_DEFINE (scm_make_hash_table, "make-hash-table", 0, 1, 0,
|
|||
}
|
||||
#undef FUNC_NAME
|
||||
|
||||
static void*
|
||||
weak_gc_callback (void *hook_data, void *fn_data, void *data)
|
||||
/* The before-gc C hook only runs if GC_set_start_callback is available,
|
||||
so if not, fall back on a finalizer-based implementation. */
|
||||
static int
|
||||
weak_gc_callback (void **weak)
|
||||
{
|
||||
void **weak = fn_data;
|
||||
void *val = weak[0];
|
||||
void (*callback) (SCM) = weak[1];
|
||||
|
||||
if (val)
|
||||
callback (PTR2SCM (val));
|
||||
else
|
||||
scm_c_hook_remove (&scm_before_gc_c_hook, weak_gc_callback, weak);
|
||||
if (!val)
|
||||
return 0;
|
||||
|
||||
callback (PTR2SCM (val));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_GC_SET_START_CALLBACK
|
||||
static void*
|
||||
weak_gc_hook (void *hook_data, void *fn_data, void *data)
|
||||
{
|
||||
if (!weak_gc_callback (fn_data))
|
||||
scm_c_hook_remove (&scm_before_gc_c_hook, weak_gc_hook, fn_data);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
static void
|
||||
weak_gc_finalizer (void *ptr, void *data)
|
||||
{
|
||||
if (weak_gc_callback (ptr))
|
||||
GC_REGISTER_FINALIZER_NO_ORDER (ptr, weak_gc_finalizer, data, NULL, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
scm_c_register_weak_gc_callback (SCM obj, void (*callback) (SCM))
|
||||
|
@ -442,7 +461,11 @@ scm_c_register_weak_gc_callback (SCM obj, void (*callback) (SCM))
|
|||
weak[1] = (void*)callback;
|
||||
GC_GENERAL_REGISTER_DISAPPEARING_LINK (weak, SCM2PTR (obj));
|
||||
|
||||
scm_c_hook_add (&scm_before_gc_c_hook, weak_gc_callback, weak, 0);
|
||||
#ifdef HAVE_GC_SET_START_CALLBACK
|
||||
scm_c_hook_add (&scm_before_gc_c_hook, weak_gc_hook, weak, 0);
|
||||
#else
|
||||
GC_REGISTER_FINALIZER_NO_ORDER (weak, weak_gc_finalizer, NULL, NULL, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
SCM_DEFINE (scm_make_weak_key_hash_table, "make-weak-key-hash-table", 0, 1, 0,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue