summaryrefslogtreecommitdiff
path: root/hv.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2012-09-21 22:01:19 -0700
committerFather Chrysostomos <sprout@cpan.org>2012-09-22 17:10:43 -0700
commit895cdc83ca4f8ad093074b3bd5d0fbc1d09f7628 (patch)
tree16c8d394266ec5912ed747c3fdf883556e91dcb3 /hv.c
parentaec0c0cc27651656899efeb7c4f64d2838a9cf9e (diff)
downloadperl-895cdc83ca4f8ad093074b3bd5d0fbc1d09f7628.tar.gz
Free iterator when freeing tied hash
The current iterator was leaking when a tied hash was freed or undefined. Since we already have a mechanism, namely HvLAZYDEL, for freeing HvEITER when not referenced elsewhere, we can use that.
Diffstat (limited to 'hv.c')
-rw-r--r--hv.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/hv.c b/hv.c
index 36b70382da..14f3399a3e 100644
--- a/hv.c
+++ b/hv.c
@@ -2370,6 +2370,7 @@ Perl_hv_iternext_flags(pTHX_ HV *hv, I32 flags)
if (entry) {
sv_setsv(key, HeSVKEY_force(entry));
SvREFCNT_dec(HeSVKEY(entry)); /* get rid of previous key */
+ HeSVKEY_set(entry, NULL);
}
else {
char *k;
@@ -2377,6 +2378,7 @@ Perl_hv_iternext_flags(pTHX_ HV *hv, I32 flags)
/* one HE per MAGICAL hash */
iter->xhv_eiter = entry = new_HE(); /* HvEITER(hv) = new_HE() */
+ HvLAZYDEL_on(hv); /* make sure entry gets freed */
Zero(entry, 1, HE);
Newxz(k, HEK_BASESIZE + sizeof(const SV *), char);
hek = (HEK*)k;
@@ -2393,6 +2395,7 @@ Perl_hv_iternext_flags(pTHX_ HV *hv, I32 flags)
Safefree(HeKEY_hek(entry));
del_HE(entry);
iter->xhv_eiter = NULL; /* HvEITER(hv) = NULL */
+ HvLAZYDEL_off(hv);
return NULL;
}
}