stas 2004/01/22 13:55:50
Modified: src/modules/perl modperl_cmd.c . Changes Added: t/htdocs/vhost startup.pl t/vhost config.t t/response/TestVhost config.pm Log: fix context problems in <perl> sections and PerlModule/PerlLoadModule/PerlRequre under threaded mpms w/ PerlOptions +Parent/+Clone in Vhosts + TestVhost::config test. Revision Changes Path 1.53 +65 -24 modperl-2.0/src/modules/perl/modperl_cmd.c Index: modperl_cmd.c =================================================================== RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_cmd.c,v retrieving revision 1.52 retrieving revision 1.53 diff -u -u -r1.52 -r1.53 --- modperl_cmd.c 19 Dec 2003 01:17:31 -0000 1.52 +++ modperl_cmd.c 22 Jan 2004 21:55:49 -0000 1.53 @@ -1,5 +1,41 @@ #include "mod_perl.h" +#ifdef USE_ITHREADS + +/* + * perl context overriding and restoration is required when + * PerlOptions +Parent/+Clone is used in vhosts, and perl is used to + * at the server startup. So that <Perl> sections, PerlLoadModule, + * PerlModule and PerlRequire are all run using the right perl context + * and restore to the original context when they are done. + * + * As of perl-5.8.3 it's unfortunate that it uses PERL_GET_CONTEXT and + * doesn't rely on the passed pTHX internally. When and if perl is + * fixed to always use pTHX if available, this context switching mess + * can be removed. + */ + +#define MP_PERL_DECLARE_CONTEXT \ + PerlInterpreter *orig_perl; \ + pTHX; + +/* XXX: .htaccess support cannot use this perl with threaded MPMs */ +#define MP_PERL_OVERRIDE_CONTEXT \ + orig_perl = PERL_GET_CONTEXT; \ + aTHX = scfg->mip->parent->perl; \ + PERL_SET_CONTEXT(aTHX); + +#define MP_PERL_RESTORE_CONTEXT \ + PERL_SET_CONTEXT(orig_perl); + +#else + +#define MP_PERL_DECLARE_CONTEXT +#define MP_PERL_OVERRIDE_CONTEXT +#define MP_PERL_RESTORE_CONTEXT + +#endif + static char *modperl_cmd_unclosed_directive(cmd_parms *parms) { return apr_pstrcat(parms->pool, parms->cmd->name, @@ -105,6 +141,7 @@ MP_CMD_SRV_DECLARE(modules) { MP_dSCFG(parms->server); + MP_PERL_DECLARE_CONTEXT; if (modperl_is_running() && modperl_init_vhost(parms->server, parms->pool, NULL) != OK) @@ -113,27 +150,29 @@ } if (modperl_is_running()) { -#ifdef USE_ITHREADS - /* XXX: .htaccess support cannot use this perl with threaded MPMs */ - dTHXa(scfg->mip->parent->perl); -#endif - MP_TRACE_d(MP_FUNC, "load PerlModule %s\n", arg); + char *error = NULL; + MP_TRACE_d(MP_FUNC, "load PerlModule %s\n", arg); + + MP_PERL_OVERRIDE_CONTEXT; if (!modperl_require_module(aTHX_ arg, FALSE)) { - return SvPVX(ERRSV); + error = SvPVX(ERRSV); } + MP_PERL_RESTORE_CONTEXT; + + return error; } else { MP_TRACE_d(MP_FUNC, "push PerlModule %s\n", arg); *(const char **)apr_array_push(scfg->PerlModule) = arg; + return NULL; } - - return NULL; } MP_CMD_SRV_DECLARE(requires) { MP_dSCFG(parms->server); + MP_PERL_DECLARE_CONTEXT; if (modperl_is_running() && modperl_init_vhost(parms->server, parms->pool, NULL) != OK) @@ -142,23 +181,23 @@ } if (modperl_is_running()) { -#ifdef USE_ITHREADS - /* XXX: .htaccess support cannot use this perl with threaded MPMs */ - dTHXa(scfg->mip->parent->perl); -#endif + char *error = NULL; MP_TRACE_d(MP_FUNC, "load PerlRequire %s\n", arg); + MP_PERL_OVERRIDE_CONTEXT; if (!modperl_require_file(aTHX_ arg, FALSE)) { - return SvPVX(ERRSV); + error = SvPVX(ERRSV); } + MP_PERL_RESTORE_CONTEXT; + + return error; } else { MP_TRACE_d(MP_FUNC, "push PerlRequire %s\n", arg); *(const char **)apr_array_push(scfg->PerlRequire) = arg; + return NULL; } - - return NULL; } static MP_CMD_SRV_DECLARE2(handle_vars) @@ -332,7 +371,7 @@ /*XXX: Less than optimal */ code = apr_pstrcat(p, code, line, "\n", NULL); } - + /* Here, we have to replace our current config node for the next pass */ if (!*current) { *current = apr_pcalloc(p, sizeof(**current)); @@ -372,7 +411,7 @@ int dollar_zero_tainted; #ifdef USE_ITHREADS MP_dSCFG(s); - pTHX; + MP_PERL_DECLARE_CONTEXT; #endif if (!(arg && *arg)) { @@ -386,10 +425,7 @@ return "init mod_perl vhost failed"; } -#ifdef USE_ITHREADS - /* XXX: .htaccess support cannot use this perl with threaded MPMs */ - aTHX = scfg->mip->parent->perl; -#endif + MP_PERL_OVERRIDE_CONTEXT; /* data will be set by a <Perl> section */ if ((options = parms->directive->data)) { @@ -443,7 +479,9 @@ if (SvTRUE(ERRSV)) { SV *strict; if ((strict = MP_STRICT_PERLSECTIONS_SV) && SvTRUE(strict)) { - return SvPVX(ERRSV); + char *error = SvPVX(ERRSV); + MP_PERL_RESTORE_CONTEXT; + return error; } else { modperl_log_warn(s, apr_psprintf(p, "Syntax error at %s:%d %s", @@ -473,12 +511,15 @@ } if (status != OK) { - return SvTRUE(ERRSV) ? SvPVX(ERRSV) : + char *error = SvTRUE(ERRSV) ? SvPVX(ERRSV) : apr_psprintf(p, "<Perl> handler %s failed with status=%d", handler->name, status); + MP_PERL_RESTORE_CONTEXT; + return error; } } + MP_PERL_RESTORE_CONTEXT; return NULL; } @@ -515,7 +556,7 @@ char line[MAX_STRING_LEN]; while (!ap_cfg_getline(line, sizeof(line), parms->config_file)) { - /* soak up rest of the file */ + /* soak up rest of the file */ } return NULL; 1.1 modperl-2.0/t/htdocs/vhost/startup.pl Index: startup.pl =================================================================== use warnings; use strict; use Apache2; use Apache::ServerUtil (); use Apache::Server (); use File::Spec::Functions qw(catdir); # base server # XXX: at the moment this is wrong, since it return the base server $s and not the vhost's one. needs to be fixed. my $s = Apache->server; my $vhost_doc_root = catdir Apache::Server::server_root, qw(htdocs vhost); # testing $s->add_config() in vhost my $conf = <<"EOC"; # must use PerlModule here to check for segfaults # and that the module is loaded by vhost PerlModule TestVhost::config PerlSetVar DocumentRootCheck $vhost_doc_root <Location /TestVhost__config> SetHandler modperl PerlResponseHandler TestVhost::config::my_handler </Location> EOC $s->add_config([split /\n/, $conf]); # this used to have problems on win32 $s->add_config(['<Perl >', '1;', '</Perl>']); 1; 1.1 modperl-2.0/t/vhost/config.t Index: config.t =================================================================== # the handler is configured in modperl_extra.pl via # Apache->server->add_config use Apache::TestUtil; use Apache::TestRequest 'GET'; my $config = Apache::Test::config(); my $vars = $config->{vars}; my $module = 'TestVhost::config'; my $path = Apache::TestRequest::module2path($module); Apache::TestRequest::module($module); my $hostport = Apache::TestRequest::hostport($config); t_debug("connecting to $hostport"); my $res = GET "http://$hostport/$path"; if ($res->is_success) { print $res->content; } else { if ($res->code == 404) { my $documentroot = $vars->{documentroot}; die "this test gets its <Location> configuration added via " . "$documentroot/vhost/startup.pl, this could be the cause " . "of the failure"; } else { die "server side has failed (response code: ", $res->code, "),\n", "see t/logs/error_log for more details\n"; } } 1.1 modperl-2.0/t/response/TestVhost/config.pm Index: config.pm =================================================================== package TestVhost::config; # Test whether under threaded mpms (and not) a vhost with 'PerlOptions # +Parent', can run <Perl> sections, which call into config again via # add_config(). use strict; use warnings FATAL => 'all'; use Apache::Test; use Apache::TestUtil; use Apache::RequestUtil (); use APR::Table (); use File::Spec::Functions qw(catdir); use Apache::Const -compile => 'OK'; # 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; { my $expected = $r->document_root; my $received = $r->dir_config->get('DocumentRootCheck'); ok t_cmp($expected, $received, "DocumentRoot"); } Apache::OK; } 1; __END__ <NoAutoConfig> <VirtualHost TestVhost::config> DocumentRoot @documentroot@/vhost <IfDefine PERL_USEITHREADS> # a new interpreter pool PerlOptions +Parent </IfDefine> # use test system's @INC PerlSwitches [EMAIL PROTECTED]@ # mp2 modules PerlRequire "@serverroot@/conf/modperl_inc.pl" # private to this vhost stuff PerlRequire "@documentroot@/vhost/startup.pl" # <Location /TestVhost__config> container is added via add_config # in t/htdocs/vhost/startup.pl </VirtualHost> </NoAutoConfig> 1.307 +4 -0 modperl-2.0/Changes Index: Changes =================================================================== RCS file: /home/cvs/modperl-2.0/Changes,v retrieving revision 1.306 retrieving revision 1.307 diff -u -u -r1.306 -r1.307 --- Changes 19 Jan 2004 20:00:17 -0000 1.306 +++ Changes 22 Jan 2004 21:55:50 -0000 1.307 @@ -12,6 +12,10 @@ =item 1.99_13-dev +fix context problems in <perl> sections and +PerlModule/PerlLoadModule/PerlRequre under threaded mpms w/ +PerlOptions +Parent/+Clone in Vhosts + TestVhost::config test. [Stas] + moved many functions out of the Apache:: namespace: Apache::unescape_url() is now Apache::URI::unescape_url() Apache::log_pid() is now Apache::Log::log_pid()