diff options
author | Jarkko Hietaniemi <jhi@iki.fi> | 2001-02-21 14:15:25 +0000 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2001-02-21 14:15:25 +0000 |
commit | 75f9d97acc061d6b37c97f17f5ff3195bd7e6f51 (patch) | |
tree | 5607ede2e9ecd3dcdb0f966e24d1897cc51fa0c7 /sv.c | |
parent | e1c57cef4ab5e7ff7a568c339d671a16148368b3 (diff) | |
download | perl-75f9d97acc061d6b37c97f17f5ff3195bd7e6f51.tar.gz |
Integrate change #8868 from pureperl to mainline.
Fixed reference count loop caused by sv_magic.
p4raw-link: @8868 on //depot/maint-5.6/pureperl: 1ccf3d77864c3a3bec62b1f24e34a456f495c987
p4raw-id: //depot/perl@8872
p4raw-integrated: from //depot/maint-5.6/pureperl@8870 'merge in' sv.c
(@8842..)
Diffstat (limited to 'sv.c')
-rw-r--r-- | sv.c | 14 |
1 files changed, 12 insertions, 2 deletions
@@ -3946,10 +3946,20 @@ Perl_sv_magic(pTHX_ register SV *sv, SV *obj, int how, const char *name, I32 nam } Newz(702,mg, 1, MAGIC); mg->mg_moremagic = SvMAGIC(sv); - SvMAGIC(sv) = mg; - if (!obj || obj == sv || how == '#' || how == 'r') + + /* Some magic sontains a reference loop, where the sv and object refer to + each other. To prevent a avoid a reference loop that would prevent such + objects being freed, we look for such loops and if we find one we avoid + incrementing the object refcount. */ + if (!obj || obj == sv || how == '#' || how == 'r' || + (SvTYPE(obj) == SVt_PVGV && + (GvSV(obj) == sv || GvHV(obj) == (HV*)sv || GvAV(obj) == (AV*)sv || + GvCV(obj) == (CV*)sv || GvIOp(obj) == (IO*)sv || + GvFORM(obj) == (CV*)sv))) + { mg->mg_obj = obj; + } else { mg->mg_obj = SvREFCNT_inc(obj); mg->mg_flags |= MGf_REFCOUNTED; |