I'm posting this to the modperl list as well as embperl in hope that 
someone there can answer some questions.

I've been trying to get the latest Embperl beta working on MacOS X 
(although apparently the problems I'm experience occur on some other 
operating systems as well).  Embperl 2.0b7, Apache 1.3.23, mod_perl 
1.26. Gerald's going on a well-deserved vacation starting about now, 
but I think some of these questions are not specific to Embperl.

1. *Why* are the apache config files executed twice (completely with 
loading and unloading all the modules)?  At least one module even has 
code to check and only do an initialization the second time it is 
called!
2. Why doesn't mod_perl force the Perl interpreter to restart when 
that happens, so that the initialization the second time is identical 
to the first time?
3. Why does mod_perl only delete $INC entries if there is a <perl> 
directive in the config file?
4. Why doesn't deleting the $INC entry force the second Require 
(executed as a result of the PerlModule command) to actually load the 
perl library again?

Here's what I believe is *supposed* to happen with Embperl.

mod_perl is loaded
PerlModule Embperl causes Embperl.pm to load, which calls an init 
function, which calls ap_add_module which causes Embperl to be 
installed as a full-fledged apache module (complete with added syntax 
for the config file).

Here's what *actually* happens.

On the first pass through the config file, everything happens exactly 
as described above.
On the second pass (more on that in a minute) through the config 
file, mod_perl does a Require of Embperl, Embperl.pm has already been 
loaded, so it isn't executed, the init call doesn't get called, the 
module doesn't get loaded, everything breaks.

Quite by accident I discovered that if I put the following code in my 
config file, things got a little bit better.
<perl>
</perl>

Now on the second pass through the config file, mod_perl calls delete 
$INC{'Embperl.pm'} and the require loads the file again.  At least in 
theory.

That actually got me to the point where Embperl runs.  But oddly, the 
config file extensions don't get parsed (e.g. I can't use any of 
Embperl's extensions to the config file syntax).  The module isn't 
completely registered.

So, to make a long story short.  I had to do a number of things to 
make this work.  Some are Embperl specific, some I think relate to 
problems with the mod_perl architecture.

1. In Embperl's Apache cleanup handler, always unload embperl.c, even 
if mod_perl isn't loaded dynamically.
2. In Embperl's init routine, *always* call ap_add_module, even if we 
weren't called from the Embperl.pm startup.
3. In the config file, explicitly call Embperl::Init in <perl></perl> 
tags.  You have to do this because on the second pass through the 
config file it isn't called at the right times.  It will get 
correctly called when PerlHandler Embperl is found, but that's too 
late for some config file directives.

That all sounds confusing, here's a trace (of the working version) to 
clear it up (hah!).  First, here's my <perl> section in the config 
file.
<Perl>
print STDERR "**** Before 1\n";
print STDERR '#', $INC{"Embperl.pm"}, "#\n";
print STDERR "**** Before 2\n";
</Perl>
PerlModule Embperl
<Perl>
print STDERR "**** After 1\n";
print STDERR '#', $INC{"Embperl.pm"}, "#\n";
Embperl::Init();
print STDERR "**** After 2\n";
</Perl>

and the trace

$ MOD_PERL_TRACE=all sudo /usr/local/apache/bin/httpd  -X
perl_parse args: '/dev/null' ...allocating perl interpreter...ok
constructing perl interpreter...ok
ok
running perl interpreter...ok
mod_perl: 0 END blocks encountered during server startup
loading perl module 'Apache'...loading perl module 
'Apache::Constants::Exports'...ok
ok
loading perl module 'Tie::IxHash'...ok


Okay, cool we've loaded and started perl.  Now we check and see if 
$INC has been set for Embperl.


**** Before 1
##
**** Before 2
perl_section: </Files>
perl_section: </Location>
perl_section: </Files>
perl_section: </Location>
perl_section: </Directory>
perl_section: </Directory>
perl_section: </VirtualHost>
loading perl module 'Apache'...ok

And now we do the PerlModule Embperl.  It correctly calls the init 
functions, which correctly call add_module.


PerlModule: arg='Embperl'
loading perl module 'Embperl'...
## called embperl_INit (0x3C40EC)
## 1 calling add_module
## 2 calling add_module
ok
bootstrapping <Perl> sections: arg=Embperl, keys=8
loading perl module 'Apache'...ok
loading perl module 'Tie::IxHash'...ok
perl_section: </Files>
perl_section: </Location>
perl_section: </Files>
perl_section: </Location>
perl_section: </Directory>
perl_section: </Directory>
perl_section: </VirtualHost>
mod_perl: delete $INC{'Embperl.pm'} (klen=10)

Look ma, it just deleted the $INC entry so if we require it again it 
will load again.  Maybe.


loading perl module 'Apache'...ok
loading perl module 'Tie::IxHash'...ok
**** After 1
##


Now I call the init function from my code.  This time around it won't 
do anything because it was already properly loaded.


## called embperl_INit (0x0)
Caling addmodule anyway
## 1 calling add_module
## not calling add_module
**** After 2
perl_section: </Files>
perl_section: </Location>
perl_section: </Files>
perl_section: </Location>
perl_section: </Directory>
perl_section: </Directory>
perl_section: </VirtualHost>

PerlHandler gets called.  And it calls the real module init routine 
for the first time.  That also calls Embperl::Init, but with 
different arguments.  Previously this was the only time that 
add_module would get called.  Note that this is too late in the 
process if we want to be able to process config directives after the 
PerlModule call, not after the PerlHandler call.


init `PerlHandler' stack
perl_cmd_push_handlers: @PerlHandler, 'Embperl'
pushing `Embperl' into `PerlHandler' handlers
ap_init_modules: embperl.c->init(0xD3308, 0xD32E0)
embperl_apacheInit(0xD3308, 0xD32E0)

## called embperl_INit (0x0)
Caling addmodule anyway
## 1 calling add_module
## not calling add_module
ap_init_modules: mod_perl.c->init(0xD3308, 0xD32E0)
loading perl module 'Apache'...ok
perl_startup: perl aleady running...ok
ap_init_modules: mod_unique_id.c->init(0xD3308, 0xD32E0)
ap_init_modules: mod_proxy.c->init(0xD3308, 0xD32E0)
ap_init_modules: mod_rewrite.c->init(0xD3308, 0xD32E0)
ap_init_modules: mod_status.c->init(0xD3308, 0xD32E0)
ap_init_modules: mod_mime.c->init(0xD3308, 0xD32E0)
ap_init_modules: mod_mime_magic.c->init(0xD3308, 0xD32E0)
ap_init_modules: mod_log_config.c->init(0xD3308, 0xD32E0)


Okay that was fun.  Now let's run the entire config file again.  (!!!!?)


loading perl module 'Apache'...ok
cleanup_sv: SvREFCNT(0x345238)==1
loading perl module 'Apache'...ok
loading perl module 'Apache'...ok
loading perl module 'Tie::IxHash'...ok


Nothing in $INC, nothing up my sleeve.


**** Before 1
##
**** Before 2
perl_section: </Files>
perl_section: </Location>
perl_section: </Files>
perl_section: </Location>
perl_section: </Directory>
perl_section: </Directory>
perl_section: </VirtualHost>
loading perl module 'Apache'...ok

Ah, time to load our perl module.  Should load fine because there was 
nothing in $INC, right?


PerlModule: arg='Embperl'
loading perl module 'Embperl'...ok


Hey!  It wasn't reloaded!  If it had been, we would have seen the 
init() call there.


bootstrapping <Perl> sections: arg=Embperl, keys=8
loading perl module 'Apache'...ok
loading perl module 'Tie::IxHash'...ok
perl_section: </Files>
perl_section: </Location>
perl_section: </Files>
perl_section: </Location>
perl_section: </Directory>
perl_section: </Directory>
perl_section: </VirtualHost>
loading perl module 'Apache'...ok
loading perl module 'Tie::IxHash'...ok
**** After 1
#/Library/Perl/darwin/Embperl.pm#

## called embperl_INit (0x0)
Caling addmodule anyway
## 1 calling add_module
## 2 calling add_module
**** After 2

And there we confirm it.  Note that nobody called delete $INC this 
time around, and when we call add_module, it adds it, which means 
nobody had got around to adding it before.


perl_section: </Files>
perl_section: </Location>
perl_section: </Files>
perl_section: </Location>
perl_section: </Directory>
perl_section: </Directory>
perl_section: </VirtualHost>
init `PerlHandler' stack
perl_cmd_push_handlers: @PerlHandler, 'Embperl'
pushing `Embperl' into `PerlHandler' handlers
[Fri Mar 22 10:43:22 2002] [warn] pid file 
/usr/local/apache/logs/httpd.pid overwritten -- Unclean shutdown of 
previous Apache run?

And now we do the normal module inits.


ap_init_modules: embperl.c->init(0xD3308, 0xD32E0)
embperl_apacheInit(0xD3308, 0xD32E0)

## called embperl_INit (0x0)
Caling addmodule anyway
## 1 calling add_module
## not calling add_module
ap_init_modules: mod_perl.c->init(0xD3308, 0xD32E0)
loading perl module 'Apache'...ok
`PerlRestartHandler' push_handlers() stack is empty
PerlRestartHandler handlers returned -1
ap_init_modules: mod_unique_id.c->init(0xD3308, 0xD32E0)
ap_init_modules: mod_proxy.c->init(0xD3308, 0xD32E0)
ap_init_modules: mod_rewrite.c->init(0xD3308, 0xD32E0)
ap_init_modules: mod_status.c->init(0xD3308, 0xD32E0)
ap_init_modules: mod_mime.c->init(0xD3308, 0xD32E0)
ap_init_modules: mod_mime_magic.c->init(0xD3308, 0xD32E0)
ap_init_modules: mod_log_config.c->init(0xD3308, 0xD32E0)
perl_init_ids: uid=-2, euid=-2, gid=70, egid=70
`PerlChildInitHandler' push_handlers() stack is empty
PerlChildInitHandler handlers returned -1


So, I have a work-around.  But I think there is something 
fundamentally wrong.  Embperl is doing a couple odd things that work 
around the problem on some systems, but don't work on other systems. 
However the whole thing could be fixed (I believe) by doing one of 
two things.

1. Don't read the damn config file twice.
2. If you have to do #1, then restart the Perl interpreter each time 
the config file is read.

Comments?

P.S. Anyone want someone to write an apache module for them?  I might 
as well put everything I've learned in the past few days to *some* 
use!
-- 

Kee Hinckley - Somewhere.Com, LLC
http://consulting.somewhere.com/
[EMAIL PROTECTED]

I'm not sure which upsets me more: that people are so unwilling to accept
responsibility for their own actions, or that they are so eager to regulate
everyone else's.

Reply via email to