diff options
Diffstat (limited to 'libguile/hashtab.c')
-rw-r--r-- | libguile/hashtab.c | 52 |
1 files changed, 37 insertions, 15 deletions
diff --git a/libguile/hashtab.c b/libguile/hashtab.c index a76c03812..48660d75c 100644 --- a/libguile/hashtab.c +++ b/libguile/hashtab.c @@ -418,32 +418,54 @@ SCM_DEFINE (scm_make_hash_table, "make-hash-table", 0, 1, 0, } #undef FUNC_NAME -static void -weak_gc_callback (void *ptr, 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 = ptr; - void *val = *weak; + void *val = weak[0]; + void (*callback) (SCM) = weak[1]; - if (val) - { - void (*callback) (SCM) = data; + if (!val) + return 0; + + callback (PTR2SCM (val)); - GC_REGISTER_FINALIZER_NO_ORDER (ptr, weak_gc_callback, data, NULL, NULL); - - 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)) { - void **weak = GC_MALLOC_ATOMIC (sizeof (void**)); + void **weak = GC_MALLOC_ATOMIC (sizeof (void*) * 2); - *weak = SCM2PTR (obj); + weak[0] = SCM2PTR (obj); + weak[1] = (void*)callback; GC_GENERAL_REGISTER_DISAPPEARING_LINK (weak, SCM2PTR (obj)); - GC_REGISTER_FINALIZER_NO_ORDER (weak, weak_gc_callback, (void*)callback, - NULL, NULL); +#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, |