Joe Schaefer wrote: [...]
That's correct (in the case of threaded mpm), but again the problem exists
before the first clone is done, since it's quite possible that the parent
interpreter is the one that compiles the perl code with anon sub, in
which case you can't attach the parent perl interpreter to that
compiled code.
I'm still confused by this line of reasoning, because it seems
you're not distinguishing between compile time vs runtime, but the problem might just be a difference in terminology. Perhaps this will help- suppose
"C" = perl code which contains an anon sub "S", e.g. using the above
$s->push_handlers(PerlPreConnectionHandler => sub { .... });
(C represents the whole line, and S is just the anon sub).
Please clarify/comment/correct the following:
If interpreter I compiles C, but does not execute it,
and then I clones J, J will not have any problem executing C.
J will never get to run C since it was already compiled by I, (I suppose you meant S in the end of that sentence)
(I'd rather have called them P(arent) and W(orker) but let's stick to I and J)
J has a problem executing S. CV/I is stored in the modperl struct. On perl_clone() call, CV/J is not the same as CV/I, so J can't call CV address generated by I (it'll be a sure segfault).
This problem could be solved for example by pushing the return value of sub {} into a scalar behind the scenes. so the code:
package Foo; $s->push_handlers(PerlPreConnectionHandler => sub { .... });
could be converted into:
package Foo; $Foo::__anonsub1 = sub { .... }; $s->push_handlers(PerlPreConnectionHandler => $Foo::__anonsub1);
of course we aren't going to manipulate the code, but just introduce a new scalar which will store that value. If we do that, when perl_clone is called the new variable will correctly contain a pointer to a new anon-sub. So all we need to store in the mod_perl struct is the name of that scalar.
I think that will work, if one can ensure that all anon-subs are compiled before perl_clone is called. But that can't be ensured.
However, it is desirable that J should also be the interpreter which executes S - the anon sub which was created by J's execution of C. Because if we guarantee that only J will execute S, we avoid the (slow, and occasionally unreliable) deparse/reparse cycle that a different interpreter would require. If we cannot make
that guarantee, J must deparse S when it executes C (and observing
that I actually compiled both C and S).
Sorry, but I can't see how can this stick interpreter-in work in the perlscope environment.
I think the simplest solution we could try in order to avoid B::Deparse is to ensure that any anon-subs are compiled before perl_clone (i.e. croak if any anon-sub is encountered after the startup phase). Combined with my idea from above (if it proves to work) that will ensure that anon-sub will be identical to named subs and the problem is solved. Since $Foo::__anonsub1 will function as a name for the sub.
The same solution can be applied for:
PerlTransHandler 'sub { ... }'
by compiling it after startup (not waiting till the run-time) and perl_clone will ensure to clone those correctly. but this is just an optimization for the inlined handlers.
-- __________________________________________________________________ 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]