summaryrefslogtreecommitdiff
path: root/mg.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 /mg.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 'mg.c')
-rw-r--r--mg.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/mg.c b/mg.c
index 63de61249f..299d1bbb11 100644
--- a/mg.c
+++ b/mg.c
@@ -359,8 +359,17 @@ Perl_mg_free(pTHX_ SV *sv)
else if (mg->mg_len == HEf_SVKEY)
SvREFCNT_dec((SV*)mg->mg_ptr);
}
- if (mg->mg_flags & MGf_REFCOUNTED)
- SvREFCNT_dec(mg->mg_obj);
+ if (mg->mg_flags & MGf_REFCOUNTED) {
+ SV *obj = mg->mg_obj;
+ if (mg->mg_type == PERL_MAGIC_tiedscalar && SvROK(obj) &&
+ (SvRV(obj) == sv || GvIO(SvRV(obj)) == (IO *) sv)) {
+ /* We are already free'ing the self-tied thing
+ so SvREFCNT_dec must not.
+ */
+ SvROK_off(obj);
+ }
+ SvREFCNT_dec(obj);
+ }
Safefree(mg);
}
SvMAGIC(sv) = 0;