diff options
author | Abhijit Menon-Sen <ams@wiw.org> | 2001-08-11 11:48:19 +0530 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2001-08-12 13:56:18 +0000 |
commit | ff76feabe05d384b669cf347124af347cb9ad879 (patch) | |
tree | 226d867acb5d1d5ec504b3e64146f5d20163e2f4 /mg.c | |
parent | 4ba0502e5961da529150fbb2a715432f1866ff19 (diff) | |
download | perl-ff76feabe05d384b669cf347124af347cb9ad879.tar.gz |
Re: [ID 20010730.010] FETCH called twice with -T
Message-ID: <20010811061819.P526@lustre.dyn.wiw.org>
p4raw-id: //depot/perl@11641
Diffstat (limited to 'mg.c')
-rw-r--r-- | mg.c | 52 |
1 files changed, 33 insertions, 19 deletions
@@ -93,34 +93,48 @@ Do magic after a value is retrieved from the SV. See C<sv_magic>. int Perl_mg_get(pTHX_ SV *sv) { - I32 mgs_ix; - MAGIC* mg; - MAGIC** mgp; - int mgp_valid = 0; + int new = 0; + MAGIC *newmg, *head, *cur, *mg; + I32 mgs_ix = SSNEW(sizeof(MGS)); - mgs_ix = SSNEW(sizeof(MGS)); save_magic(mgs_ix, sv); - mgp = &SvMAGIC(sv); - while ((mg = *mgp) != 0) { - MGVTBL* vtbl = mg->mg_virtual; + /* We must call svt_get(sv, mg) for each valid entry in the linked + list of magic. svt_get() may delete the current entry, add new + magic to the head of the list, or upgrade the SV. AMS 20010810 */ + + newmg = cur = head = mg = SvMAGIC(sv); + while (mg) { + MGVTBL *vtbl = mg->mg_virtual; + if (!(mg->mg_flags & MGf_GSKIP) && vtbl && vtbl->svt_get) { CALL_FPTR(vtbl->svt_get)(aTHX_ sv, mg); - /* Ignore this magic if it's been deleted */ - if ((mg == (mgp_valid ? *mgp : SvMAGIC(sv))) && - (mg->mg_flags & MGf_GSKIP)) - (SSPTR(mgs_ix, MGS*))->mgs_flags = 0; + /* Don't restore the flags for this entry if it was deleted. */ + if (mg->mg_flags & MGf_GSKIP) + (SSPTR(mgs_ix, MGS *))->mgs_flags = 0; } - /* Advance to next magic (complicated by possible deletion) */ - if (mg == (mgp_valid ? *mgp : SvMAGIC(sv))) { - mgp = &mg->mg_moremagic; - mgp_valid = 1; + + mg = mg->mg_moremagic; + + if (new) { + /* Have we finished with the new entries we saw? Start again + where we left off (unless there are more new entries). */ + if (mg == head) { + new = 0; + mg = cur; + head = newmg; + } + } + + /* Were any new entries added? */ + if (!new && (newmg = SvMAGIC(sv)) != head) { + new = 1; + cur = mg; + mg = newmg; } - else - mgp = &SvMAGIC(sv); /* Re-establish pointer after sv_upgrade */ } - restore_magic(aTHXo_ INT2PTR(void*, (IV)mgs_ix)); + restore_magic(aTHXo_ INT2PTR(void *, (IV)mgs_ix)); return 0; } |