Return-Path: Delivered-To: apmail-perl-dev-archive@www.apache.org Received: (qmail 28948 invoked from network); 16 Dec 2004 00:51:02 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur-2.apache.org with SMTP; 16 Dec 2004 00:51:02 -0000 Received: (qmail 99168 invoked by uid 500); 16 Dec 2004 00:51:02 -0000 Delivered-To: apmail-perl-dev-archive@perl.apache.org Received: (qmail 99151 invoked by uid 500); 16 Dec 2004 00:51:01 -0000 Mailing-List: contact dev-help@perl.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: list-post: Delivered-To: mailing list dev@perl.apache.org Received: (qmail 99135 invoked by uid 99); 16 Dec 2004 00:51:01 -0000 X-ASF-Spam-Status: No, hits=0.0 required=10.0 tests= X-Spam-Check-By: apache.org Received-SPF: pass (hermes.apache.org: domain of gozer@ectoplasm.org designates 66.34.202.202 as permitted sender) Received: from Unknown (HELO minerva.ectoplasm.org) (66.34.202.202) by apache.org (qpsmtpd/0.28) with ESMTP; Wed, 15 Dec 2004 16:49:09 -0800 Received: from [172.28.57.123] (office4.tmcs.net [209.104.55.5]) by minerva.ectoplasm.org (Postfix) with ESMTP id 814045EB20 for ; Wed, 15 Dec 2004 14:44:30 -0800 (PST) Message-ID: <41C0BF15.4090004@ectoplasm.org> Date: Wed, 15 Dec 2004 14:47:49 -0800 From: "Philippe M. Chiasson" User-Agent: Mozilla Thunderbird 0.9 (X11/20041127) X-Accept-Language: en-us, en MIME-Version: 1.0 To: dev@perl.apache.org Subject: [Patch mp2] PerlConfigRequire && PerlPostConfigRequire X-Enigmail-Version: 0.89.0.0 X-Enigmail-Supports: pgp-inline, pgp-mime Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="------------enig226BA36654C74BF85A090172" X-Virus-Checked: Checked X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N --------------enig226BA36654C74BF85A090172 Content-Type: multipart/mixed; boundary="------------060101060002000407060700" This is a multi-part message in MIME format. --------------060101060002000407060700 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Here is a new version of my original patch that includes tests (no doc though) -------------------------------------------------------------------------------- Philippe M. Chiasson m/gozer\@(apache|cpan|ectoplasm)\.org/ GPG KeyID : 88C3A5A5 http://gozer.ectoplasm.org/ F9BF E0C2 480E 7680 1AE5 3631 CB32 A107 88C3A5A5 --------------060101060002000407060700 Content-Type: text/x-patch; name="PerlPostConfigRequire.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="PerlPostConfigRequire.patch" Index: src/modules/perl/mod_perl.c =================================================================== --- src/modules/perl/mod_perl.c (revision 112024) +++ src/modules/perl/mod_perl.c (working copy) @@ -326,6 +326,10 @@ if (!modperl_config_apply_PerlModule(s, scfg, perl, p)) { exit(1); } + + if (!modperl_config_prepare_PerlPostConfigRequire(s, scfg, perl, p)) { + exit(1); + } #ifndef USE_ITHREADS cdata = modperl_cleanup_data_new(server_pool, (void*)perl); @@ -414,6 +418,10 @@ if (!modperl_config_apply_PerlModule(s, scfg, perl, p)) { return HTTP_INTERNAL_SERVER_ERROR; } + + if (!modperl_config_prepare_PerlPostConfigRequire(s, scfg, perl, p)) { + return HTTP_INTERNAL_SERVER_ERROR; + } } #ifdef USE_ITHREADS @@ -466,6 +474,17 @@ } +static int modperl_post_config_require(server_rec *s, apr_pool_t *p) +{ + for (; s; s=s->next) { + MP_dSCFG(s); + if (!modperl_config_apply_PerlPostConfigRequire(s, scfg, p)) { + return FALSE; + } + } + return TRUE; +} + #ifdef USE_ITHREADS static void modperl_init_clones(server_rec *s, apr_pool_t *p) { @@ -646,6 +665,11 @@ MP_dSCFG(s); dTHXa(scfg->mip->parent->perl); #endif + + if (!modperl_post_config_require(s, pconf)) { + exit(1); + } + if (modperl_threaded_mpm()) { MP_threads_started = 1; } @@ -860,6 +884,8 @@ MP_CMD_SRV_ITERATE("PerlSwitches", switches, "Perl Switches"), MP_CMD_DIR_ITERATE("PerlModule", modules, "PerlModule"), MP_CMD_DIR_ITERATE("PerlRequire", requires, "PerlRequire"), + MP_CMD_SRV_ITERATE("PerlConfigRequire", config_requires, "PerlConfigRequire"), + MP_CMD_SRV_ITERATE("PerlPostConfigRequire", post_config_requires, "PerlPostConfigRequire"), MP_CMD_DIR_ITERATE("PerlOptions", options, "Perl Options"), MP_CMD_DIR_ITERATE("PerlInitHandler", init_handlers, "Subroutine name"), MP_CMD_DIR_TAKE2("PerlSetVar", set_var, "PerlSetVar"), Index: src/modules/perl/modperl_config.c =================================================================== --- src/modules/perl/modperl_config.c (revision 112024) +++ src/modules/perl/modperl_config.c (working copy) @@ -155,6 +155,8 @@ scfg->PerlModule = apr_array_make(p, 2, sizeof(char *)); scfg->PerlRequire = apr_array_make(p, 2, sizeof(char *)); + scfg->PerlPostConfigRequire = + apr_array_make(p, 1, sizeof(modperl_require_file_t *)); scfg->argv = apr_array_make(p, 2, sizeof(char *)); @@ -285,6 +287,7 @@ merge_item(modules); merge_item(PerlModule); merge_item(PerlRequire); + merge_item(PerlPostConfigRequire); merge_table_overlap_item(SetEnv); merge_table_overlap_item(PassEnv); @@ -437,6 +440,53 @@ return TRUE; } +int modperl_config_apply_PerlPostConfigRequire(server_rec *s, + modperl_config_srv_t *scfg, + apr_pool_t *p) +{ + modperl_require_file_t **requires; + int i; + + requires = (modperl_require_file_t **)scfg->PerlPostConfigRequire->elts; + for (i = 0; i < scfg->PerlPostConfigRequire->nelts; i++){ + if (modperl_require_file( requires[i]->perl, requires[i]->file, TRUE)){ + MP_TRACE_d(MP_FUNC, "loaded Perl file: %s for server %s\n", + requires[i]->file, modperl_server_desc(s,p)); + } + else { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Can't load Perl file: %s for server %s, exiting...", + requires[i]->file, modperl_server_desc(s,p)); + return FALSE; + } + } + + return TRUE; +} + +/* In the case where files were added when interpreters were not yet started, + * we need to go over the existing files and assign them the correct interpreter + */ +int modperl_config_prepare_PerlPostConfigRequire(server_rec *s, + modperl_config_srv_t *scfg, + PerlInterpreter *perl, + apr_pool_t *p) +{ + modperl_require_file_t **requires; + int i; + + requires = (modperl_require_file_t **)scfg->PerlPostConfigRequire->elts; + for (i = 0; i < scfg->PerlPostConfigRequire->nelts; i++) { + if (!requires[i]->perl) { + MP_TRACE_d(MP_FUNC, "Late binding of %s to an interpreter", + requires[i]->file); + requires[i]->perl = perl; + } + } + + return 1; +} + typedef struct { AV *av; I32 ix; Index: src/modules/perl/modperl_types.h =================================================================== --- src/modules/perl/modperl_types.h (revision 112024) +++ src/modules/perl/modperl_types.h (working copy) @@ -65,6 +65,13 @@ }; typedef struct { + const char *file; +#ifdef USE_ITHREADS + PerlInterpreter *perl; +#endif +} modperl_require_file_t; + +typedef struct { /* s == startup grow * r == runtime grow */ @@ -130,7 +137,7 @@ MpHV *configvars; MpHV *SetEnv; MpHV *PassEnv; - MpAV *PerlRequire, *PerlModule; + MpAV *PerlRequire, *PerlModule, *PerlPostConfigRequire; MpAV *handlers_per_srv[MP_HANDLER_NUM_PER_SRV]; MpAV *handlers_files[MP_HANDLER_NUM_FILES]; MpAV *handlers_process[MP_HANDLER_NUM_PROCESS]; Index: src/modules/perl/modperl_config.h =================================================================== --- src/modules/perl/modperl_config.h (revision 112024) +++ src/modules/perl/modperl_config.h (working copy) @@ -122,6 +122,15 @@ modperl_config_srv_t *scfg, PerlInterpreter *perl, apr_pool_t *p); +int modperl_config_prepare_PerlPostConfigRequire(server_rec *s, + modperl_config_srv_t *scfg, + PerlInterpreter *perl, + apr_pool_t *p); + +int modperl_config_apply_PerlPostConfigRequire(server_rec *s, + modperl_config_srv_t *scfg, + apr_pool_t *p); + const char *modperl_config_insert(pTHX_ server_rec *s, apr_pool_t *p, apr_pool_t *ptmp, Index: src/modules/perl/modperl_cmd.c =================================================================== --- src/modules/perl/modperl_cmd.c (revision 112024) +++ src/modules/perl/modperl_cmd.c (working copy) @@ -266,6 +266,49 @@ } } +MP_CMD_SRV_DECLARE(config_requires) +{ + /* we must init earlier than normal */ + modperl_run(); + + /* PerlConfigFile is only different from PerlRequires by forcing + * an immediate init. + */ + return modperl_cmd_requires(parms, mconfig, arg); +} + +MP_CMD_SRV_DECLARE(post_config_requires) +{ + MP_dSCFG(parms->server); + MP_PERL_DECLARE_CONTEXT; + apr_pool_t *p = parms->pool; + apr_finfo_t finfo; + + if (APR_SUCCESS == apr_stat(&finfo, arg, APR_FINFO_TYPE, p)) { + if (finfo.filetype != APR_NOFILE) { + modperl_require_file_t *require = apr_pcalloc(p, sizeof(*require)); +#ifdef USE_ITHREADS + if (modperl_is_running()) { + MP_PERL_OVERRIDE_CONTEXT; + require->perl = aTHX; + MP_PERL_RESTORE_CONTEXT; + } +#endif + require->file = arg; + + MP_TRACE_d(MP_FUNC, "push PerlPostConfigRequire for %s\n", arg); + + *(modperl_require_file_t **) + apr_array_push(scfg->PerlPostConfigRequire) = require; + } + } + else { + return apr_pstrcat(p, "No such file : ", arg, NULL); + } + + return NULL; +} + static void modperl_cmd_addvar_func(apr_table_t *configvars, apr_table_t *setvars, const char *key, const char *val) Index: src/modules/perl/modperl_cmd.h =================================================================== --- src/modules/perl/modperl_cmd.h (revision 112024) +++ src/modules/perl/modperl_cmd.h (working copy) @@ -39,6 +39,8 @@ MP_CMD_SRV_DECLARE(switches); MP_CMD_SRV_DECLARE(modules); MP_CMD_SRV_DECLARE(requires); +MP_CMD_SRV_DECLARE(config_requires); +MP_CMD_SRV_DECLARE(post_config_requires); MP_CMD_SRV_DECLARE2(set_var); MP_CMD_SRV_DECLARE2(add_var); MP_CMD_SRV_DECLARE2(set_env); Index: t/htdocs/vhost/post_config.pl =================================================================== --- t/htdocs/vhost/post_config.pl (revision 0) +++ t/htdocs/vhost/post_config.pl (revision 0) @@ -0,0 +1,9 @@ +use warnings; +use strict; + +use Apache2; +use Apache::ServerUtil (); + +$TestVhost::config::Restart_Count = Apache::ServerUtil::restart_count(); + +1; Index: t/conf/modperl_extra.pl =================================================================== --- t/conf/modperl_extra.pl (revision 112024) +++ t/conf/modperl_extra.pl (working copy) @@ -33,8 +33,6 @@ reorg_INC(); -register_post_config_startup(); - startup_info(); test_add_config(); @@ -70,19 +68,6 @@ @INC = (@a, @b, @c); } -# need to run from config phase, since it registers PerlPostConfigHandler -sub register_post_config_startup { - # most of the startup code needs to be run at the post_config - # phase - Apache->server->push_handlers(PerlPostConfigHandler => sub { - my $pool = Apache->server->process->pool; - my $t_conf_path = Apache::ServerUtil::server_root_relative($pool, - "conf"); - require "$t_conf_path/post_config_startup.pl"; - return Apache::OK; - }); -} - # this can be run from post_config_startup.pl, but then it'll do the # logging twice, so in this case it's actually good to have this code # run during config phase, so it's logged only once (even though it's Index: t/response/TestVhost/config.pm =================================================================== --- t/response/TestVhost/config.pm (revision 112024) +++ t/response/TestVhost/config.pm (working copy) @@ -17,19 +17,25 @@ use Apache::Const -compile => 'OK'; +our $Restart_Count; + # using a different from 'handler' name on purpose, to make sure # that the module is preloaded at the server startup sub my_handler { my $r = shift; - plan $r, tests => 1; + plan $r, tests => 2; { my $expected = $r->document_root; my $received = $r->dir_config->get('DocumentRootCheck'); ok t_cmp(canonpath($received), canonpath($expected), "DocumentRoot"); } - + + { + ok t_cmp($Restart_Count, 2, "PerlPostConfigRequire"); + } + Apache::OK; } @@ -56,6 +62,7 @@ # private to this vhost stuff PerlRequire "@documentroot@/vhost/startup.pl" + PerlPostConfigRequire "@documentroot@/vhost/post_config.pl" # container is added via add_config # in t/htdocs/vhost/startup.pl Index: Changes =================================================================== --- Changes (revision 112024) +++ Changes (working copy) @@ -12,6 +12,14 @@ =item 1.99_19-dev +New configuration directives: [Gozer] + - PerlConfigRequire + Just like PerlRequire, but _always_ triggers an immediate + interpreter startup + - PerlPostConfigRequire + A delayed form of PerlRequire, that waits until the post_config + phase before require'ing files + Ignore Apache-Test/META.yml in distribution tarballs until PAUSE is capable of handling multiple META.yml files in one distro [Gozer] --------------060101060002000407060700-- --------------enig226BA36654C74BF85A090172 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.6 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org iD8DBQFBwL8VyzKhB4jDpaURAm8MAJ0RfK/HWQtDyI9k3Ze09z1ffc1HzQCfa4rf dKjsIcRhUXGynospwNNS0wg= =2p9O -----END PGP SIGNATURE----- --------------enig226BA36654C74BF85A090172--