Stas Bekman wrote:
It looks like 5.8.1 started to cache ppids in PL_ppid, which wasn't the case in 5.8.0. When ithreads are enabled the new logic updates PL_ppid in pp_fork, which now does:
PP(pp_fork) { ... #ifdef THREADS_HAVE_PIDS PL_ppid = (IV)getppid(); #endif
THREADS_HAVE_PIDS is only defined on Linux. The relevant section of the docs is in perlvar/$$ :
Note for Linux users: on Linux, the C functions C<getpid()> and C<getppid()> return different values from different threads. In order to be portable, this behavior is not reflected by C<$$>, whose value remains consistent across threads. If you want to call the underlying C<getpid()>, you may use the CPAN module C<Linux::Pid>.
Yes, but we aren't talking threads here. This behavior is true under mp2/prefork mpm where we have no threads, but processes. We run in the threads-friendly environment, so you can spawn threads if you want to (e.g. if you want to use more than one perl interpreter under the same process).
>So if an application running embedded perl wasn't forked by perl's pp_fork, it'll have this problem. Under mod_perl 2, we get getppid reporting 1 from the forked process, when pstree clearly shows that this is not the case.
Yes. I didn't thought about this problem.
I have a workaround for mp2:
#if PERL_REVISION == 5 && PERL_VERSION == 8 && PERL_SUBVERSION == 1 { #ifdef THREADS_HAVE_PIDS #ifdef USE_ITHREADS MP_dSCFG(s); dTHXa(scfg->mip->parent->perl); PL_ppid = (IV)getppid(); #endif #endif } #endif
which can be run at the child_init phase, immediately after a new process is forked. But may be it's something that need to be fixed in perl, as it worked just fine with 5.8.0, and is probably an inappropriate change in behavior for a maintenance release? If not please let me know, so that I'll change the workaround's ifdef to match 5.8.1+.
Currently PL_ppid is initialized in S_init_postdump_symbols. I imagine we could initialize or reinitialize it later at a time more suitable if there is some routine to be called back at fork time.
I don't think this should be a responsibility of the application, it's quite possible that that the application embedding perl has no callback/event to know when to call this special initialization.
I think the really proper algorithm is to leave the current behavior
only if perl was the one who did the fork (which will probably require yet another PL_ flag. And if that flag is not set the pp_getppid logic should be changed to cache that value and raise that flag. Something like this:
PP(pp_fork) { ... #ifdef THREADS_HAVE_PIDS PL_ppid = (IV)getppid(); PL_ppid_cached = 1; #endif
PP(pp_getppid) { ... { #ifdef HAS_GETPPID dSP; dTARGET; # ifdef THREADS_HAVE_PIDS if (!PL_ppid_cached) { PL_ppid = (IV)getppid(); PL_ppid_cached = 1; } XPUSHi( PL_ppid ); # else XPUSHi( getppid() ); # endif RETURN; #else DIE(aTHX_ PL_no_func, "getppid"); #endif }
of course needing to init PL_ppid_cached to 0 when created and make sure that threads init it to 0 as well, I suppose. this is untested, just an idea. Or maybe initting PL_ppid to 0, can serve the same purpose as the newly suggested flag PL_ppid_cached. So the logic would be then:
PP(pp_getppid) { ... { #ifdef HAS_GETPPID dSP; dTARGET; # ifdef THREADS_HAVE_PIDS if (!PL_ppid) { PL_ppid = (IV)getppid(); } XPUSHi( PL_ppid ); # else ...
without any changes to pp_fork
Perhaps should I add a note in perlembed.pod about this problem ?
First of all, do you think this change (if left unmodified) is suitable for a maintenance release?
__________________________________________________________________ Stas Bekman JAm_pH ------> Just Another mod_perl Hacker http://stason.org/ mod_perl Guide ---> http://perl.apache.org mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com http://modperlbook.org http://apache.org http://ticketmaster.com
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]