summaryrefslogtreecommitdiff
path: root/sv.c
diff options
context:
space:
mode:
authorNick Ing-Simmons <nik@tiuk.ti.com>2002-05-27 09:54:46 +0000
committerNick Ing-Simmons <nik@tiuk.ti.com>2002-05-27 09:54:46 +0000
commit3977871ddaef13bab4556a4c080d3871df7b231f (patch)
tree1a63841ea2569dcbb1eca7744a1722cf1154f18e /sv.c
parent2628be26342842a5f886163d0568170afde998a0 (diff)
downloadperl-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.c26
1 files changed, 12 insertions, 14 deletions
diff --git a/sv.c b/sv.c
index dd35da7c1f..7d51f322ba 100644
--- a/sv.c
+++ b/sv.c
@@ -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