mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 11:50:28 +02:00
fix subtle and bad scm_internal_hash_fold bug for weak tables
* libguile/hashtab.c (scm_internal_hash_fold): Don't try to unlink deleted weak pairs. Our previous code was buggy (`prev' should have only been updated in the case of a successful traversal), but more than that, we're not in the alloc lock. Thanks very much to Michael Wells for the report, and the debugging!
This commit is contained in:
parent
dfb572a7bf
commit
2187975e39
1 changed files with 10 additions and 30 deletions
|
@ -1377,40 +1377,20 @@ scm_internal_hash_fold (scm_t_hash_fold_fn fn, void *closure,
|
||||||
n = SCM_SIMPLE_VECTOR_LENGTH (buckets);
|
n = SCM_SIMPLE_VECTOR_LENGTH (buckets);
|
||||||
for (i = 0; i < n; ++i)
|
for (i = 0; i < n; ++i)
|
||||||
{
|
{
|
||||||
SCM prev, ls;
|
SCM ls, handle;
|
||||||
|
|
||||||
for (prev = SCM_BOOL_F, ls = SCM_SIMPLE_VECTOR_REF (buckets, i);
|
for (ls = SCM_SIMPLE_VECTOR_REF (buckets, i); !scm_is_null (ls);
|
||||||
!scm_is_null (ls);
|
ls = SCM_CDR (ls))
|
||||||
prev = ls, ls = SCM_CDR (ls))
|
|
||||||
{
|
{
|
||||||
SCM handle;
|
|
||||||
|
|
||||||
if (!scm_is_pair (ls))
|
|
||||||
SCM_WRONG_TYPE_ARG (SCM_ARG3, buckets);
|
|
||||||
|
|
||||||
handle = SCM_CAR (ls);
|
handle = SCM_CAR (ls);
|
||||||
if (!scm_is_pair (handle))
|
|
||||||
SCM_WRONG_TYPE_ARG (SCM_ARG3, buckets);
|
|
||||||
|
|
||||||
if (SCM_HASHTABLE_WEAK_P (table))
|
if (SCM_HASHTABLE_WEAK_P (table) && SCM_WEAK_PAIR_DELETED_P (handle))
|
||||||
{
|
/* Don't try to unlink this weak pair, as we're not within
|
||||||
if (SCM_WEAK_PAIR_DELETED_P (handle))
|
the allocation lock. Instead rely on
|
||||||
{
|
vacuum_weak_hash_table to do its job. */
|
||||||
/* We hit a weak pair whose car/cdr has become
|
continue;
|
||||||
unreachable: unlink it from the bucket. */
|
else
|
||||||
if (scm_is_true (prev))
|
result = fn (closure, SCM_CAR (handle), SCM_CDR (handle), result);
|
||||||
SCM_SETCDR (prev, SCM_CDR (ls));
|
|
||||||
else
|
|
||||||
SCM_SIMPLE_VECTOR_SET (buckets, i, SCM_CDR (ls));
|
|
||||||
|
|
||||||
/* Update the item count. */
|
|
||||||
SCM_HASHTABLE_DECREMENT (table);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result = fn (closure, SCM_CAR (handle), SCM_CDR (handle), result);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue