diff options
author | Nicholas Clark <nick@ccl4.org> | 2005-12-31 16:57:32 +0000 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2005-12-31 16:57:32 +0000 |
commit | 2e58978ba658da6c974603284c681a91f2905990 (patch) | |
tree | ce369eb6137bff01539b4f8720b901e779521d37 | |
parent | 7440661e2628bf13f68b1828cf423db52f268294 (diff) | |
download | perl-2e58978ba658da6c974603284c681a91f2905990.tar.gz |
Calling Perl_hv_clear_placeholders while the hash iterator was active
would turn lazy delete on, causing the hash to become corrupted at the
next iterator change.
p4raw-id: //depot/perl@26551
-rw-r--r-- | hv.c | 2 | ||||
-rw-r--r-- | lib/Hash/Util.t | 21 |
2 files changed, 21 insertions, 2 deletions
@@ -1617,7 +1617,7 @@ Perl_hv_clear_placeholders(pTHX_ HV *hv) *oentry = HeNEXT(entry); if (first && !*oentry) HvFILL(hv)--; /* This linked list is now empty. */ - if (HvEITER_get(hv)) + if (entry == HvEITER_get(hv)) HvLAZYDEL_on(hv); else hv_free_ent(hv, entry); diff --git a/lib/Hash/Util.t b/lib/Hash/Util.t index 8ed557f1a3..adce3d171d 100644 --- a/lib/Hash/Util.t +++ b/lib/Hash/Util.t @@ -6,7 +6,7 @@ BEGIN { chdir 't'; } } -use Test::More tests => 173; +use Test::More tests => 179; use strict; my @Exported_Funcs; @@ -323,3 +323,22 @@ ok($hash_seed >= 0, "hash_seed $hash_seed"); is ($counter, 0, "0 objects after clear $state"); } } + +{ + my %hash = map {$_,$_} qw(fwiffffff foosht teeoo); + lock_keys(%hash); + delete $hash{fwiffffff}; + is (scalar keys %hash, 2); + unlock_keys(%hash); + is (scalar keys %hash, 2); + + my ($first, $value) = each %hash; + is ($hash{$first}, $value, "Key has the expected value before the lock"); + lock_keys(%hash); + is ($hash{$first}, $value, "Key has the expected value after the lock"); + + my ($second, $v2) = each %hash; + + is ($hash{$first}, $value, "Still correct after iterator advances"); + is ($hash{$second}, $v2, "Other key has the expected value"); +} |