* libguile/weak-table.c (move_weak_entry): Change to return a Boolean. (give_to_poor): Remove 'copy_weak_entry' call and adjust accordingly. --- libguile/weak-table.c | 46 +++++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 17 deletions(-)
diff --git a/libguile/weak-table.c b/libguile/weak-table.c index b5db3ef48..5c4b3d30a 100644 --- a/libguile/weak-table.c +++ b/libguile/weak-table.c @@ -199,28 +199,45 @@ move_disappearing_links (scm_t_weak_entry *from, scm_t_weak_entry *to, } } -static void +/* Move weak entry FROM to TO. Return non-zero on success, and zero if + the entry at FROM disappeared in the meantime. */ +static int move_weak_entry (scm_t_weak_entry *from, scm_t_weak_entry *to, scm_t_weak_table_kind kind) { if (from->hash) { scm_t_weak_entry copy; - + copy_weak_entry (from, ©); - to->hash = copy.hash; - to->key = copy.key; - to->value = copy.value; - move_disappearing_links (from, to, - SCM_PACK (copy.key), SCM_PACK (copy.value), - kind); + if (copy.key != 0 && copy.value != 0) + { + to->hash = copy.hash; + to->key = copy.key; + to->value = copy.value; + + move_disappearing_links (from, to, + SCM_PACK (copy.key), SCM_PACK (copy.value), + kind); + return 1; + } + else + { + /* Lost weak reference: make sure all the disappearing links + are registered (in the case of a doubly-weak table, one of + the disappearing links could still be there.) */ + memset (to, '\0', sizeof *to); + unregister_disappearing_links (from, kind); + return 0; + } } else { + unregister_disappearing_links (from, kind); to->hash = 0; - to->key = 0; - to->value = 0; + to->key = to->value = 0; + return 0; } } @@ -301,16 +318,14 @@ give_to_poor (scm_t_weak_table *table, unsigned long k) { unsigned long next = (k + 1) % size; unsigned long hash; - scm_t_weak_entry copy; hash = table->entries[next].hash; if (!hash || hash_to_index (hash, size) == next) break; - copy_weak_entry (&table->entries[next], ©); - - if (!copy.key || !copy.value) + if (!move_weak_entry (&table->entries[next], &table->entries[k], + table->kind)) /* Lost weak reference. */ { give_to_poor (table, next); @@ -318,9 +333,6 @@ give_to_poor (scm_t_weak_table *table, unsigned long k) continue; } - move_weak_entry (&table->entries[next], &table->entries[k], - table->kind); - k = next; } -- 2.14.2