summaryrefslogtreecommitdiff
path: root/mg.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2011-06-13 22:44:15 -0700
committerFather Chrysostomos <sprout@cpan.org>2011-06-13 22:47:30 -0700
commit9cdac2a22a8bffa5e715bb52fc23ec5f89562d4f (patch)
treeaf4860db4aa73ee44ddc5688a9dc2ff6846f5702 /mg.c
parent5cfe25fd495495a0961237ddf3346dfeb47e7137 (diff)
downloadperl-9cdac2a22a8bffa5e715bb52fc23ec5f89562d4f.tar.gz
Make $$ writable, but still magical
This commit makes $$ writable again, as it was in 5.6, while preserv- ing the magical pid-fetching added recently (post-5.14.0) by com- mit 0e219455. It does this by following Aristotle Pagaltzis’ brilliant suggestion in <20110609145148.GD8471@klangraum.plasmasturm.org>; namely, to store the PID in magic when $$ is written to, so that get-magic can detect whether a fork() has occurred and reset $$ accordingly. This makes it seem as though the fork() code sets $$ itself (which it used to before 0e219455), while even working when C code outside of perl’s control calls fork(). This restores compatibility with DBIx::Connector and PPerl.
Diffstat (limited to 'mg.c')
-rw-r--r--mg.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/mg.c b/mg.c
index 86f1eb6e4d..1bdf5c4cda 100644
--- a/mg.c
+++ b/mg.c
@@ -1080,7 +1080,13 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg)
sv_copypv(sv, PL_ors_sv);
break;
case '$': /* $$ */
- sv_setiv(sv, (IV)PerlProc_getpid());
+ {
+ IV const pid = (IV)PerlProc_getpid();
+ if (isGV(mg->mg_obj) || SvIV(mg->mg_obj) != pid)
+ /* never set manually, or at least not since last fork */
+ sv_setiv(sv, pid);
+ /* else a value has been assigned manually, so do nothing */
+ }
break;
case '!':
@@ -2881,6 +2887,17 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg)
case ':':
PL_chopset = SvPV_force(sv,len);
break;
+ case '$': /* $$ */
+ /* Store the pid in mg->mg_obj so we can tell when a fork has
+ occurred. mg->mg_obj points to *$ by default, so clear it. */
+ if (isGV(mg->mg_obj)) {
+ if (mg->mg_flags & MGf_REFCOUNTED) /* probably never true */
+ SvREFCNT_dec(mg->mg_obj);
+ mg->mg_flags |= MGf_REFCOUNTED;
+ mg->mg_obj = newSViv((IV)PerlProc_getpid());
+ }
+ else sv_setiv(mg->mg_obj, (IV)PerlProc_getpid());
+ break;
case '0':
LOCK_DOLLARZERO_MUTEX;
#ifdef HAS_SETPROCTITLE