Philippe M. Chiasson wrote:
Here is a new version of my original patch that includes tests (no doc though)
+ merge_item(PerlPostConfigRequire);
I was wondering if it makes sense to merge this one.
It's necessary, for the same reason PerlRequire or PerlModule has to be merged. Otherwise, the vhost config for PerlPostConfigRequire will get lost in the merge. (You'll notice my original patch wasn't merging and wasn't working as a side effect)
+
Philippe, mind you not add lines like: /^ $/, I have to cleanup those after every of your commits :( Any chance your editor can be configured not to add those space padding?
Yes, sorry 'bout that. I've figured out how to avoid this hapenning with my favorite (unnamed) editor ;-).
BTW, I noticed that there are a lot of these kind of /^ $/ in src/modules/perl/*.c as of today. If you want, I'll go thru them and make a whitespace cleanup patch later on today.
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;
should be:
use strict; use warnings FATAL => 'all';
Yes
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;
anything wrong with $restart_count? and I'd add a comment:
# initialized in t/htdocs/vhost/post_config.pl
Good thoughs. Patch attached.
-------------------------------------------------------------------------------- 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
Index: src/modules/perl/mod_perl.c
===================================================================
--- src/modules/perl/mod_perl.c (revision 112024)
+++ src/modules/perl/mod_perl.c (working copy)
@@ -327,6 +327,10 @@
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);
apr_pool_cleanup_register(server_pool, cdata,
@@ -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 strict;
+use warnings FATAL => 'all';
+
+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,26 @@
use Apache::Const -compile => 'OK';
+# initialized in t/htdocs/vhost/post_config.pl
+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 +63,7 @@
# private to this vhost stuff
PerlRequire "@documentroot@/vhost/startup.pl"
+ PerlPostConfigRequire "@documentroot@/vhost/post_config.pl"
# <Location /TestVhost__config> 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]
signature.asc
Description: OpenPGP digital signature
