It helps to set the total keys correctly when duplicating a hash.
Nicholas Clark [Thu, 26 May 2005 11:28:24 +0000 (11:28 +0000)]
It helps even more to have a test for this.

p4raw-id: //depot/perl@24582

ext/threads/t/problems.t
sv.c

index f468813..b43a5f0 100644 (file)
@@ -13,12 +13,13 @@ use warnings;
 use strict;
 use threads;
 use threads::shared;
+use Hash::Util 'lock_keys';
 
 # Note that we can't use  Test::More here, as we would need to
 # call is() from within the DESTROY() function at global destruction time,
 # and parts of Test::* may have already been freed by then
 
-print "1..10\n";
+print "1..14\n";
 
 my $test : shared = 1;
 
@@ -26,7 +27,7 @@ sub is($$$) {
     my ($got, $want, $desc) = @_;
     unless ($got eq $want) {
        print "# EXPECTED: $want\n";
-       print "# GOT:      got\n";
+       print "# GOT:      $got\n";
        print "not ";
     }
     print "ok $test - $desc\n";
@@ -120,4 +121,20 @@ for my $decl ('my $x : unique', 'sub foo : unique') {
 # print $string eq 'foobar' ?  '' : 'not ', "ok $test - returning closure\n";
 # $test++;
 
+# Nothing is checking that total keys gets cloned correctly.
+
+my %h = (1,2,3,4);
+is (keys %h, 2, "keys correct in parent");
+
+my $child = threads->new(sub { return scalar keys %h })->join;
+is ($child, 2, "keys correct in child");
+
+lock_keys (%h);
+delete $h{1};
+
+is (keys %h, 1, "keys correct in parent with restricted hash");
+
+$child = threads->new(sub { return scalar keys %h })->join;
+is ($child, 1, "keys correct in child with restricted hash");
+
 1;
diff --git a/sv.c b/sv.c
index b0571d8..74c05c8 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -10909,6 +10909,7 @@ Perl_sv_dup(pTHX_ SV *sstr, CLONE_PARAMS* param)
        SvANY(dstr)     = new_XPVHV();
        SvCUR_set(dstr, SvCUR(sstr));
        SvLEN_set(dstr, SvLEN(sstr));
+       HvTOTALKEYS(dstr) = HvTOTALKEYS(sstr);
        SvMAGIC_set(dstr, mg_dup(SvMAGIC(sstr), param));
        SvSTASH_set(dstr, hv_dup_inc(SvSTASH(sstr), param));
        {