diff options
author | Nicholas Clark <nick@ccl4.org> | 2002-12-02 21:48:29 +0000 |
---|---|---|
committer | Rafael Garcia-Suarez <rgarciasuarez@gmail.com> | 2002-12-08 19:34:34 +0000 |
commit | 015a5f36be663aa2533aa485ced211ebada3b063 (patch) | |
tree | dd534e2adfb0e1bd3ed7f50bacea4e146b68f42b /hv.c | |
parent | 8edd5f42cf54cdbf0218037ce0d38a9e2e2d58d9 (diff) | |
download | perl-015a5f36be663aa2533aa485ced211ebada3b063.tar.gz |
Re: [perl #18651] Hash::Util's lock_key() breaks hash
Message-ID: <20021202214828.GA284@Bagpuss.unfortu.net>
p4raw-id: //depot/perl@18259
Diffstat (limited to 'hv.c')
-rw-r--r-- | hv.c | 16 |
1 files changed, 12 insertions, 4 deletions
@@ -1855,6 +1855,7 @@ Perl_hv_iternext_flags(pTHX_ HV *hv, I32 flags) Newz(506, xhv->xhv_array /* HvARRAY(hv) */, PERL_HV_ARRAY_ALLOC_BYTES(xhv->xhv_max+1 /* HvMAX(hv)+1 */), char); + /* At start of hash, entry is NULL. */ if (entry) { entry = HeNEXT(entry); @@ -1869,8 +1870,11 @@ Perl_hv_iternext_flags(pTHX_ HV *hv, I32 flags) } } while (!entry) { + /* OK. Come to the end of the current list. Grab the next one. */ + xhv->xhv_riter++; /* HvRITER(hv)++ */ if (xhv->xhv_riter > (I32)xhv->xhv_max /* HvRITER(hv) > HvMAX(hv) */) { + /* There is no next one. End of the hash. */ xhv->xhv_riter = -1; /* HvRITER(hv) = -1 */ break; } @@ -1878,10 +1882,14 @@ Perl_hv_iternext_flags(pTHX_ HV *hv, I32 flags) entry = ((HE**)xhv->xhv_array)[xhv->xhv_riter]; if (!(flags & HV_ITERNEXT_WANTPLACEHOLDERS)) { - /* if we have an entry, but it's a placeholder, don't count it */ - if (entry && HeVAL(entry) == &PL_sv_undef) - entry = 0; - } + /* If we have an entry, but it's a placeholder, don't count it. + Try the next. */ + while (entry && HeVAL(entry) == &PL_sv_undef) + entry = HeNEXT(entry); + } + /* Will loop again if this linked list starts NULL + (for HV_ITERNEXT_WANTPLACEHOLDERS) + or if we run through it and find only placeholders. */ } if (oldentry && HvLAZYDEL(hv)) { /* was deleted earlier? */ |