diff options
author | Andy Wingo <wingo@pobox.com> | 2011-04-15 18:05:23 +0200 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2011-04-15 18:05:23 +0200 |
commit | 631e49ed767a877fc1776dc5b07818512fdc8c06 (patch) | |
tree | a6817dfbb3e7371af86ce89b1b125849de7dde52 | |
parent | cc3546b027336c554218351d8a755866c9560948 (diff) | |
download | guile-631e49ed767a877fc1776dc5b07818512fdc8c06.tar.gz |
weak hash table vacuum on before-gc C hook
* libguile/hashtab.c (weak_gc_callback)
(scm_c_register_weak_gc_callback): Change implementation to use the
before-gc C hook instead of the after-gc finalizers.
-rw-r--r-- | libguile/hashtab.c | 27 |
1 files changed, 13 insertions, 14 deletions
diff --git a/libguile/hashtab.c b/libguile/hashtab.c index a76c03812..f5c86a56f 100644 --- a/libguile/hashtab.c +++ b/libguile/hashtab.c @@ -418,32 +418,31 @@ SCM_DEFINE (scm_make_hash_table, "make-hash-table", 0, 1, 0, } #undef FUNC_NAME -static void -weak_gc_callback (void *ptr, void *data) +static void* +weak_gc_callback (void *hook_data, void *fn_data, void *data) { - void **weak = ptr; - void *val = *weak; + void **weak = fn_data; + void *val = weak[0]; + void (*callback) (SCM) = weak[1]; if (val) - { - void (*callback) (SCM) = data; + callback (PTR2SCM (val)); + else + scm_c_hook_remove (&scm_before_gc_c_hook, weak_gc_callback, weak); - GC_REGISTER_FINALIZER_NO_ORDER (ptr, weak_gc_callback, data, NULL, NULL); - - callback (PTR2SCM (val)); - } + return NULL; } 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); + scm_c_hook_add (&scm_before_gc_c_hook, weak_gc_callback, weak, 0); } SCM_DEFINE (scm_make_weak_key_hash_table, "make-weak-key-hash-table", 0, 1, 0, |