On Fri 05 Dec 2008, Kostas Chatzikokolakis wrote:
> I'd like to ask what is the intended behaviour of
>  Apache2::ServerUtil->server->push_handlers(PerlCleanupHandler =>
> ...) compared to
>  Apache2::RequestUtil->request->push_handlers(PerlCleanupHandler =>
> ...)
>
> On my Ubuntu 8.10 (mod_perl 2.0.4, apache 2.2.9) cleanup handlers
> installed on $s seem to be called after *every* request but handlers
> installed on $r are called only *once* after the *current* request.
> On a RedHat ES 5 (mod_perl 2.0.2, apache 2.2.3) cleanup handlers on
> $s look like they are never called.
>
> I found and old list message suggesting that cleanup handlers on $s
> are called when the server is terminated, but this doesn't seem to be
> the case (and looks strange since we have PerlChildExitHandler for
> that). In the documentation of handlers, there is no mention of where
> each handler must be installed and whether it makes a difference.
>
>
> NOTE: on my Ubuntu, a cleanup handler installed on $s is called only
> if there are also other types of handlers on $s. In the Changelog of
> the *threading branch* I found the following message
>
>   Now correctly invokes PerlCleanupHandlers, even if they are the
> only handler type configured for that request [Torsten Foertsch]
>
> this comes from r594609 but it was not merged for 2.0.4. This maybe
> happens also for $r handlers, but on my setup $r has always at least
> a PerlResponseHandler so I'm not sure.

Apache request configuration is performed in 2 steps. The first occurs 
at startup the second at runtime. At startup one configuration object 
per virtual server is created. At runtime a request inherits from that 
config but other request specific configuration sources (Location 
blocks, .htaccess files etc) are merged.

$s->push_handlers as well as $s->add_config modify the server 
configuration object while $r->... modify the runtime request 
configuration. The server methods are intended to be used only at 
startup time (up to PerlPostConfig, perhaps PerlChildInit works too). 
Later the server configuration must be read-only or you risk segfaults 
at least on a threaded MPM.

The PerlCleanup phase is an artificial thing that is implemented as a 
pool cleanup function on the request pool. But it needs to be 
registered on the request pool to be run. If there is no Perl handler 
in the request cycle the pool cleanup is never installed. The patch you 
mentioned fixes that but it depends on an other interpreter management 
(the heart of the threading branch). Hence, if you need that use the 
threading branch. I use it for quite a time now in production with 
prefork. I know there are issues with worker. So, I don't recommend 
that.

In modperl_callback.c at line 202 you'll find these lines:

   /* XXX: would like to do this in modperl_hook_create_request()
    * but modperl_interp_select() is what figures out if
    * PerlInterpScope eq handler, in which case we do not register
    * a cleanup.  modperl_hook_create_request() is also currently always
    * run even if modperl isn't handling any part of the request
    */
   modperl_config_req_cleanup_register(r, rcfg);

This is inside the modperl_callback_run_handlers() function which is the 
central point that runs all PerlXXXHandlers. That's why you need at 
least one PerlXXXHandler to activate the PerlCleanupHandler. In the 
threading branch the modperl_config_req_cleanup_register() call could 
have been moved to the create_request hook as mentioned in the comment.

Torsten

-- 
Need professional mod_perl support?
Just hire me: [EMAIL PROTECTED]

Reply via email to