diff options
author | Nick Ing-Simmons <nik@tiuk.ti.com> | 2002-05-27 09:54:46 +0000 |
---|---|---|
committer | Nick Ing-Simmons <nik@tiuk.ti.com> | 2002-05-27 09:54:46 +0000 |
commit | 3977871ddaef13bab4556a4c080d3871df7b231f (patch) | |
tree | 1a63841ea2569dcbb1eca7744a1722cf1154f18e /sv.c | |
parent | 2628be26342842a5f886163d0568170afde998a0 (diff) | |
download | perl-3977871ddaef13bab4556a4c080d3871df7b231f.tar.gz |
Fix for the IO::Scalar bug (I think).
At tie time break the loop but in a different place:
A. Increment REFCNT of the RV involved in the self-tie
B. Decrement REFCNT of the thing RV points to (e.g. the GV)
At mg_free time
Break the connection between the RV and its referent
so that we do not try and free it (again).
p4raw-id: //depot/perlio@16808
Diffstat (limited to 'sv.c')
-rw-r--r-- | sv.c | 26 |
1 files changed, 12 insertions, 14 deletions
@@ -4479,6 +4479,15 @@ Perl_sv_magicext(pTHX_ SV* sv, SV* obj, int how, MGVTBL *vtable, else { mg->mg_obj = SvREFCNT_inc(obj); mg->mg_flags |= MGf_REFCOUNTED; + + /* Break self-tie loops */ + if (how == PERL_MAGIC_tiedscalar && SvROK(obj) && + (SvRV(obj) == sv || GvIO(SvRV(obj)) == (IO *) sv)) { + /* We have to have a REFCNT to obj, so drop REFCNT + of what if references instead + */ + SvREFCNT_dec(SvRV(obj)); + } } mg->mg_type = how; mg->mg_len = namlen; @@ -5172,20 +5181,9 @@ Perl_sv_free(pTHX_ SV *sv) } ATOMIC_DEC_AND_TEST(refcount_is_zero, SvREFCNT(sv)); if (!refcount_is_zero) { - if (SvREFCNT(sv) == 1) { - /* Break self-tie loops */ - MAGIC *mg = 0; - SV *obj; - if (SvTYPE(sv) == SVt_PVGV) - sv = (SV *)GvIO(sv); - if (!sv || !SvMAGICAL(sv) || SvTYPE(sv) < SVt_PVMG) - return; - mg = SvTIED_mg(sv, PERL_MAGIC_tiedscalar); - if (mg && (obj = mg->mg_obj) && SvROK(obj) && - (SvRV(obj) == sv || GvIO(SvRV(obj)) == (IO *) sv)) { - sv_unmagic(sv, PERL_MAGIC_tiedscalar); - } - } + /* Do not be tempted to test SvMAGIC here till scope.c + stops sharing MAGIC * between SVs + */ return; } #ifdef DEBUGGING |