summaryrefslogtreecommitdiff
path: root/sv.c
diff options
context:
space:
mode:
authorJarkko Hietaniemi <jhi@iki.fi>2001-02-21 14:15:25 +0000
committerJarkko Hietaniemi <jhi@iki.fi>2001-02-21 14:15:25 +0000
commit75f9d97acc061d6b37c97f17f5ff3195bd7e6f51 (patch)
tree5607ede2e9ecd3dcdb0f966e24d1897cc51fa0c7 /sv.c
parente1c57cef4ab5e7ff7a568c339d671a16148368b3 (diff)
downloadperl-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.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/sv.c b/sv.c
index e9dda52808..bd4e4276f2 100644
--- a/sv.c
+++ b/sv.c
@@ -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;