Perl's core exit( ) function shouldn't be used in mod_perl code. Calling it causes the mod_perl process to exit, which defeats the purpose of using mod_perl. The Apache::exit( ) function should be used instead. Starting with Perl Version 5.6.0, mod_perl overrides exit( ) behind the scenes using CORE::GLOBAL::, a new magical package.
Apache::Registry and Apache::PerlRun override exit( ) with Apache::exit( ) behind the scenes; therefore, scripts running under these modules don't need to be modified to use Apache::exit( ).
If CORE::exit( ) is used in scripts running under mod_perl, the child will exit, but the current request won't be logged. More importantly, a proper exit won't be performed. For example, if there are some database handles, they will remain open, causing costly memory and (even worse) database connection leaks.
If the child process needs to be killed, Apache::exit(Apache::Constants::DONE)should be used instead. This will cause the server to exit gracefully, completing the logging functions and protocol requirements.
If the child process needs to be killed cleanly after the request has completed, use the $r->child_terminate method. This method can be called anywhere in the code, not just at the end. This method sets the value of the MaxRequestsPerChild configuration directive to 1 and clears the keepalive flag. After the request is serviced, the current connection is broken because of the keepalive flag, which is set to false, and the parent tells the child to cleanly quit because MaxRequestsPerChild is smaller than or equal to the number of requests served.
In an Apache::Registryscript you would write:
Apache->request->child_terminate;
and in httpd.conf:
PerlFixupHandler "sub { shift->child_terminate }"
You would want to use the latter example only if you wanted the child to terminate every time the registered handler was called. This is probably not what you want.
You can also use a post-processing handler to trigger child termination. You might do this if you wanted to execute your own cleanup code before the process exits:
my $r = shift; $r->post_connection(\&exit_child); sub exit_child { # some logic here if needed $r->child_terminate; }
This is the code that is used by the Apache::SizeLimit module, which terminates processes that grow bigger than a preset quota.
 
Continue to: