dougm 00/04/27 14:42:26 Modified: lib/ModPerl Code.pm src/modules/perl mod_perl.c modperl_callback.c modperl_callback.h modperl_config.c modperl_config.h modperl_interp.c modperl_interp.h modperl_types.h Log: stash selected interp object in the given pool (c->pool or r->pool), rather than r->request_config, required for Perl*ConnectionHandlers hookup PerlOpenLogsHandler and PerlChildInitHandler Revision Changes Path 1.19 +16 -7 modperl-2.0/lib/ModPerl/Code.pm Index: Code.pm =================================================================== RCS file: /home/cvs/modperl-2.0/lib/ModPerl/Code.pm,v retrieving revision 1.18 retrieving revision 1.19 diff -u -r1.18 -r1.19 --- Code.pm 2000/04/26 07:29:24 1.18 +++ Code.pm 2000/04/27 21:42:24 1.19 @@ -8,7 +8,7 @@ #XXX Init, PreConfig my %handlers = ( Process => [qw(ChildInit ChildExit Restart)], - Files => [qw(OpenLog PostConfig)], + Files => [qw(OpenLogs PostConfig)], PerSrv => [qw(PostReadRequest Trans)], PerDir => [qw(HeaderParser Access Authen Authz @@ -30,6 +30,8 @@ Log => 'log_transaction', PreConnection => 'pre_connection', ProcessConnection => 'process_connection', + OpenLogs => 'open_logs', + ChildInit => 'child_init', ); my %hook_proto = ( @@ -60,13 +62,14 @@ my $dcfg_get = 'modperl_dir_config_t *dcfg = (modperl_dir_config_t *)dummy'; +my $scfg_get = 'MP_dSCFG(parms->server)'; + my %directive_proto = ( PerSrv => { args => [{type => 'cmd_parms', name => 'parms'}, {type => 'void', name => 'dummy'}, {type => 'char', name => 'arg'}], - cfg => {get => 'MP_dSCFG(parms->server)', - name => 'scfg'}, + cfg => {get => $scfg_get, name => 'scfg'}, scope => 'RSRC_CONF', }, PerDir => { @@ -78,12 +81,18 @@ }, ); -while (my($k,$v) = each %directive_proto) { - $directive_proto{$k}->{ret} = 'const char *'; +for my $class (qw(Process Connection Files)) { + my $lc_class = lc $class; + $directive_proto{$class}->{cfg}->{name} = "scfg->${lc_class}_cfg"; + $directive_proto{$class}->{cfg}->{get} = $scfg_get; + + for (qw(args scope)) { + $directive_proto{$class}->{$_} = $directive_proto{PerSrv}->{$_}; + } } -for (qw(Process Connection Files)) { - $directive_proto{$_} = $directive_proto{PerSrv}; +while (my($k,$v) = each %directive_proto) { + $directive_proto{$k}->{ret} = 'const char *'; } my %flags = ( 1.12 +1 -1 modperl-2.0/src/modules/perl/mod_perl.c Index: mod_perl.c =================================================================== RCS file: /home/cvs/modperl-2.0/src/modules/perl/mod_perl.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- mod_perl.c 2000/04/26 07:29:25 1.11 +++ mod_perl.c 2000/04/27 21:42:25 1.12 @@ -61,7 +61,7 @@ void modperl_register_hooks(void) { /* XXX: should be pre_config hook or 1.xx logic */ - ap_hook_open_logs(modperl_hook_init, NULL, NULL, AP_HOOK_MIDDLE); + ap_hook_open_logs(modperl_hook_init, NULL, NULL, AP_HOOK_FIRST); modperl_register_handler_hooks(); } 1.6 +52 -24 modperl-2.0/src/modules/perl/modperl_callback.c Index: modperl_callback.c =================================================================== RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_callback.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- modperl_callback.c 2000/04/25 05:57:48 1.5 +++ modperl_callback.c 2000/04/27 21:42:25 1.6 @@ -39,8 +39,7 @@ ap_status_t modperl_handler_cleanup(void *data) { modperl_handler_t *handler = (modperl_handler_t *)data; - dTHXa(handler->perl); - modperl_handler_unparse(aTHX_ handler); + modperl_handler_unparse(handler); return APR_SUCCESS; } @@ -112,8 +111,9 @@ return 0; } -void modperl_handler_unparse(pTHX_ modperl_handler_t *handler) +void modperl_handler_unparse(modperl_handler_t *handler) { + dTHXa(handler->perl); int was_parsed = handler->args || handler->cv || handler->obj; if (!MpHandlerPARSED(handler)) { @@ -153,6 +153,10 @@ char *tmp; CV *cv; +#ifdef USE_ITHREADS + handler->perl = aTHX; +#endif + if (strnEQ(name, "sub ", 4)) { handler->cv = eval_pv(name, FALSE); MP_TRACE_h(MP_FUNC, "handler is anonymous\n"); @@ -279,27 +283,46 @@ #define MP_HANDLER_TYPE_DIR 1 #define MP_HANDLER_TYPE_SRV 2 +#define MP_HANDLER_TYPE_CONN 3 +#define MP_HANDLER_TYPE_PROC 4 +#define MP_HANDLER_TYPE_FILE 5 -int modperl_run_handlers(int idx, request_rec *r, server_rec *s, int type) +int modperl_run_handlers(int idx, request_rec *r, conn_rec *c, + server_rec *s, int type) { #ifdef USE_ITHREADS pTHX; #endif MP_dSCFG(s); + MP_dDCFG; modperl_handler_t **handlers; - MpAV *av; + modperl_interp_t *interp = NULL; + MpAV *av = NULL; int i, status = OK; const char *desc = NULL; - if (type == MP_HANDLER_TYPE_DIR) { - MP_dDCFG; + switch (type) { + case MP_HANDLER_TYPE_DIR: av = dcfg->handlers[idx]; MP_TRACE_a_do(desc = modperl_per_dir_handler_desc(idx)); - } - else { + break; + case MP_HANDLER_TYPE_SRV: av = scfg->handlers[idx]; MP_TRACE_a_do(desc = modperl_per_srv_handler_desc(idx)); - } + break; + case MP_HANDLER_TYPE_CONN: + av = scfg->connection_cfg->handlers[idx]; + MP_TRACE_a_do(desc = modperl_connection_handler_desc(idx)); + break; + case MP_HANDLER_TYPE_FILE: + av = scfg->files_cfg->handlers[idx]; + MP_TRACE_a_do(desc = modperl_files_handler_desc(idx)); + break; + case MP_HANDLER_TYPE_PROC: + av = scfg->process_cfg->handlers[idx]; + MP_TRACE_a_do(desc = modperl_process_handler_desc(idx)); + break; + }; if (!av) { MP_TRACE_h(MP_FUNC, "no %s handlers configured (%s)\n", @@ -307,19 +330,13 @@ return DECLINED; } - if (r) { - MP_dRCFG; - if (!rcfg) { - rcfg = modperl_request_config_new(r); - ap_set_module_config(r->request_config, &perl_module, rcfg); - } #ifdef USE_ITHREADS - aTHX = rcfg->interp->perl; -#endif + if (r || c) { + interp = modperl_interp_select(r, c, s); + aTHX = interp->perl; } -#ifdef USE_ITHREADS else { - /* Child{Init,Exit} */ + /* Child{Init,Exit}, OpenLogs */ aTHX = scfg->mip->parent->perl; } #endif @@ -334,31 +351,42 @@ handlers[i]->name, status); } +#ifdef USE_ITHREADS + if (interp && MpInterpPUTBACK_On(interp)) { + /* XXX: might want to put interp back into available pool + * rather than have it marked as in_use for the lifetime of + * a request + */ + } +#endif + return status; } int modperl_per_dir_callback(int idx, request_rec *r) { - return modperl_run_handlers(idx, r, r->server, MP_HANDLER_TYPE_DIR); + return modperl_run_handlers(idx, r, NULL, r->server, MP_HANDLER_TYPE_DIR); } int modperl_per_srv_callback(int idx, request_rec *r) { - return modperl_run_handlers(idx, r, r->server, MP_HANDLER_TYPE_SRV); + return modperl_run_handlers(idx, r, NULL, r->server, MP_HANDLER_TYPE_SRV); } int modperl_connection_callback(int idx, conn_rec *c) { - return modperl_run_handlers(idx, NULL, c->base_server, - MP_HANDLER_TYPE_SRV); + return modperl_run_handlers(idx, NULL, c, c->base_server, + MP_HANDLER_TYPE_CONN); } void modperl_process_callback(int idx, ap_pool_t *p, server_rec *s) { + modperl_run_handlers(idx, NULL, NULL, s, MP_HANDLER_TYPE_PROC); } void modperl_files_callback(int idx, ap_pool_t *pconf, ap_pool_t *plog, ap_pool_t *ptemp, server_rec *s) { + modperl_run_handlers(idx, NULL, NULL, s, MP_HANDLER_TYPE_FILE); } 1.4 +1 -1 modperl-2.0/src/modules/perl/modperl_callback.h Index: modperl_callback.h =================================================================== RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_callback.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- modperl_callback.h 2000/04/18 22:59:15 1.3 +++ modperl_callback.h 2000/04/27 21:42:25 1.4 @@ -10,7 +10,7 @@ int modperl_handler_lookup(pTHX_ modperl_handler_t *handler, char *class, char *name); -void modperl_handler_unparse(pTHX_ modperl_handler_t *handler); +void modperl_handler_unparse(modperl_handler_t *handler); int modperl_handler_parse(pTHX_ modperl_handler_t *handler); 1.9 +16 -6 modperl-2.0/src/modules/perl/modperl_config.c Index: modperl_config.c =================================================================== RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_config.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- modperl_config.c 2000/04/21 05:25:31 1.8 +++ modperl_config.c 2000/04/27 21:42:25 1.9 @@ -43,11 +43,6 @@ modperl_request_config_t *rcfg = (modperl_request_config_t *)ap_pcalloc(r->pool, sizeof(*rcfg)); -#ifdef USE_ITHREADS - rcfg->interp = modperl_interp_select(r); - PERL_SET_INTERP(rcfg->interp->perl); -#endif - MP_TRACE_d(MP_FUNC, "0x%lx\n", (unsigned long)rcfg); return rcfg; @@ -59,11 +54,26 @@ modperl_srv_config_t *modperl_srv_config_new(ap_pool_t *p) { modperl_srv_config_t *scfg = (modperl_srv_config_t *) - ap_pcalloc(p, sizeof(modperl_srv_config_t)); + ap_pcalloc(p, sizeof(*scfg)); scfg->argv = ap_make_array(p, 2, sizeof(char *)); scfg_push_argv((char *)ap_server_argv0); + +#ifdef MP_CONNECTION_NUM_HANDLERS + scfg->connection_cfg = (modperl_connection_config_t *) + ap_pcalloc(p, sizeof(*scfg->connection_cfg)); +#endif + +#ifdef MP_FILES_NUM_HANDLERS + scfg->files_cfg = (modperl_files_config_t *) + ap_pcalloc(p, sizeof(*scfg->files_cfg)); +#endif + +#ifdef MP_PROCESS_NUM_HANDLERS + scfg->process_cfg = (modperl_process_config_t *) + ap_pcalloc(p, sizeof(*scfg->process_cfg)); +#endif MP_TRACE_d(MP_FUNC, "0x%lx\n", (unsigned long)scfg); 1.9 +2 -2 modperl-2.0/src/modules/perl/modperl_config.h Index: modperl_config.h =================================================================== RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_config.h,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- modperl_config.h 2000/04/21 05:25:31 1.8 +++ modperl_config.h 2000/04/27 21:42:25 1.9 @@ -47,8 +47,8 @@ #define MP_dDCFG \ modperl_dir_config_t *dcfg = \ - (modperl_dir_config_t *) \ - ap_get_module_config(r->per_dir_config, &perl_module) + (r ? (modperl_dir_config_t *) \ + ap_get_module_config(r->per_dir_config, &perl_module) : NULL) #define MP_dSCFG(s) \ modperl_srv_config_t *scfg = \ 1.9 +72 -5 modperl-2.0/src/modules/perl/modperl_interp.c Index: modperl_interp.c =================================================================== RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_interp.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- modperl_interp.c 2000/04/21 05:25:31 1.8 +++ modperl_interp.c 2000/04/27 21:42:25 1.9 @@ -110,7 +110,6 @@ (unsigned long)pthread_self()); #endif MpInterpIN_USE_On(interp); - MpInterpPUTBACK_On(interp); mip->in_use++; break; } @@ -121,6 +120,13 @@ } } + /* XXX: this should never happen */ + if (!interp) { + MP_TRACE_i(MP_FUNC, "PANIC: no interpreter found, %d of %d in use\n", + mip->in_use, mip->size); + abort(); + } + MUTEX_UNLOCK(&mip->mip_lock); return interp; @@ -282,13 +288,74 @@ return APR_SUCCESS; } + +/* XXX: + * interp is marked as in_use for the lifetime of the pool it is + * stashed in. this is done to avoid the mip->mip_lock whenever + * possible. neither approach is ideal. + */ +#define MP_INTERP_KEY "MODPERL_INTERP" -modperl_interp_t *modperl_interp_select(request_rec *r) +modperl_interp_t *modperl_interp_select(request_rec *r, conn_rec *c, + server_rec *s) { - modperl_interp_t *interp = modperl_interp_get(r->server); + modperl_interp_t *interp; + ap_pool_t *p = NULL; + const char *desc = NULL; + + if (c) { + desc = "conn_rec pool"; + (void)ap_get_userdata((void **)&interp, MP_INTERP_KEY, c->pool); + + if (interp) { + MP_TRACE_i(MP_FUNC, + "found interp 0x%lx in %s 0x%lx\n", + (unsigned long)interp, desc, (unsigned long)c->pool); + return interp; + } + + p = c->pool; + } + else if (r) { + desc = "request_rec pool"; + (void)ap_get_userdata((void **)&interp, MP_INTERP_KEY, r->pool); + + if (interp) { + MP_TRACE_i(MP_FUNC, + "found interp 0x%lx in %s 0x%lx\n", + (unsigned long)interp, desc, (unsigned long)r->pool); + return interp; + } + + /* might have already been set by a ConnectionHandler */ + (void)ap_get_userdata((void **)&interp, MP_INTERP_KEY, + r->connection->pool); + if (interp) { + desc = "r->connection pool"; + MP_TRACE_i(MP_FUNC, + "found interp 0x%lx in %s 0x%lx\n", + (unsigned long)interp, desc, + (unsigned long)r->connection->pool); + return interp; + } + + p = r->pool; + } + + if (!p) { + /* should never happen */ + MP_TRACE_i(MP_FUNC, "no pool\n"); + return NULL; + } + + interp = modperl_interp_get(s ? s : r->server); + + (void)ap_set_userdata((void *)interp, MP_INTERP_KEY, + modperl_interp_unselect, + p); - ap_register_cleanup(r->pool, (void*)interp, - modperl_interp_unselect, ap_null_cleanup); + MP_TRACE_i(MP_FUNC, "set interp 0x%lx in %s 0x%lx\n", + (unsigned long)interp, desc, (unsigned long)p); return interp; } 1.6 +2 -1 modperl-2.0/src/modules/perl/modperl_interp.h Index: modperl_interp.h =================================================================== RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_interp.h,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- modperl_interp.h 2000/04/21 05:25:31 1.5 +++ modperl_interp.h 2000/04/27 21:42:25 1.6 @@ -18,7 +18,8 @@ ap_status_t modperl_interp_unselect(void *data); -modperl_interp_t *modperl_interp_select(request_rec *r); +modperl_interp_t *modperl_interp_select(request_rec *r, conn_rec *c, + server_rec *s); ap_status_t modperl_interp_pool_destroy(void *data); 1.10 +1 -3 modperl-2.0/src/modules/perl/modperl_types.h Index: modperl_types.h =================================================================== RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_types.h,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- modperl_types.h 2000/04/21 05:25:31 1.9 +++ modperl_types.h 2000/04/27 21:42:25 1.10 @@ -73,6 +73,7 @@ MpAV *PassEnv; MpAV *PerlRequire, *PerlModule; MpAV *handlers[MP_PER_SRV_NUM_HANDLERS]; + modperl_files_config_t *files_cfg; modperl_process_config_t *process_cfg; modperl_connection_config_t *connection_cfg; #ifdef USE_ITHREADS @@ -98,9 +99,6 @@ } modperl_dir_config_t; typedef struct { -#ifdef USE_ITHREADS - modperl_interp_t *interp; -#endif HV *pnotes; } modperl_request_config_t;