dougm 01/03/14 21:39:09
Modified: src/modules/perl modperl_callback.c modperl_callback.h
modperl_filter.c modperl_mgv.c modperl_mgv.h
Log:
VirtualHosts configured with 'PerlOptions +Parent' need to have autoloaded
modules required into their own namespace
Revision Changes Path
1.27 +4 -4 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.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- modperl_callback.c 2001/03/14 17:28:07 1.26
+++ modperl_callback.c 2001/03/15 05:39:06 1.27
@@ -62,7 +62,7 @@
}
int modperl_callback(pTHX_ modperl_handler_t *handler, apr_pool_t *p,
- AV *args)
+ server_rec *s, AV *args)
{
CV *cv=Nullcv;
I32 flags = G_EVAL|G_SCALAR;
@@ -113,12 +113,12 @@
cv = (CV*)SvRV(sv);
}
else {
- GV *gv = modperl_mgv_lookup(aTHX_ handler->mgv_cv);
+ GV *gv = modperl_mgv_lookup_autoload(aTHX_ handler->mgv_cv, s, p);
if (gv) {
cv = modperl_mgv_cv(gv);
}
else {
- char *name = modperl_mgv_as_string(aTHX_ handler->mgv_cv, p);
+ char *name = modperl_mgv_as_string(aTHX_ handler->mgv_cv, p, 0);
MP_TRACE_h(MP_FUNC, "lookup of %s failed\n", name);
}
}
@@ -268,7 +268,7 @@
};
for (i=0; i<av->nelts; i++) {
- if ((status = modperl_callback(aTHX_ handlers[i], p, av_args)) != OK) {
+ if ((status = modperl_callback(aTHX_ handlers[i], p, s, av_args)) != OK) {
status = modperl_errsv(aTHX_ status, r, s);
}
1.15 +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.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- modperl_callback.h 2001/03/14 17:38:30 1.14
+++ modperl_callback.h 2001/03/15 05:39:07 1.15
@@ -18,7 +18,7 @@
void modperl_handler_make_args(pTHX_ AV **avp, ...);
int modperl_callback(pTHX_ modperl_handler_t *handler, apr_pool_t *p,
- AV *args);
+ server_rec *s, AV *args);
int modperl_run_handlers(int idx, request_rec *r, conn_rec *c,
server_rec *s, int type, ...);
1.9 +1 -1 modperl-2.0/src/modules/perl/modperl_filter.c
Index: modperl_filter.c
===================================================================
RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- modperl_filter.c 2001/03/14 00:37:52 1.8
+++ modperl_filter.c 2001/03/15 05:39:07 1.9
@@ -97,7 +97,7 @@
filter_classes[filter->mode], filter,
NULL);
- if ((status = modperl_callback(aTHX_ handler, p, args)) != OK) {
+ if ((status = modperl_callback(aTHX_ handler, p, s, args)) != OK) {
status = modperl_errsv(aTHX_ status, r, s);
}
1.3 +88 -11 modperl-2.0/src/modules/perl/modperl_mgv.c
Index: modperl_mgv.c
===================================================================
RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_mgv.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- modperl_mgv.c 2001/03/15 01:26:18 1.2
+++ modperl_mgv.c 2001/03/15 05:39:07 1.3
@@ -141,6 +141,33 @@
return Nullgv;
}
+#ifdef USE_ITHREADS
+MP_INLINE GV *modperl_mgv_lookup_autoload(pTHX_ modperl_mgv_t *symbol,
+ server_rec *s, apr_pool_t *p)
+{
+ MP_dSCFG(s);
+ GV *gv = modperl_mgv_lookup(aTHX_ symbol);
+
+ if (gv || !MpSrvPARENT(scfg)) {
+ return gv;
+ }
+
+ /*
+ * this VirtualHost has its own parent interpreter
+ * must require the module again with this server's THX
+ */
+ modperl_mgv_require_module(aTHX_ symbol, s, p);
+
+ return modperl_mgv_lookup(aTHX_ symbol);
+}
+#else
+MP_INLINE GV *modperl_mgv_lookup_autoload(pTHX_ modperl_mgv_t *symbol,
+ server_rec *s, apr_pool_t *p)
+{
+ return modperl_mgv_lookup(aTHX_ symbol);
+}
+#endif
+
int modperl_mgv_resolve(pTHX_ modperl_handler_t *handler,
apr_pool_t *p, const char *name)
{
@@ -257,31 +284,53 @@
}
char *modperl_mgv_as_string(pTHX_ modperl_mgv_t *symbol,
- apr_pool_t *p)
+ apr_pool_t *p, int package)
{
char *string, *ptr;
modperl_mgv_t *mgv;
int len = 0;
- for (mgv = symbol; mgv; mgv = mgv->next) {
+ for (mgv = symbol; (package ? mgv->next : mgv); mgv = mgv->next) {
len += mgv->len;
}
ptr = string = apr_palloc(p, len+1);
- for (mgv = symbol; mgv; mgv = mgv->next) {
+ for (mgv = symbol; (package ? mgv->next : mgv); mgv = mgv->next) {
Copy(mgv->name, ptr, mgv->len, char);
ptr += mgv->len;
}
- *ptr = '\0';
+ if (package) {
+ *(ptr-2) = '\0'; /* trim trailing :: */
+ }
+ else {
+ *ptr = '\0';
+ }
return string;
}
+#ifdef USE_ITHREADS
+int modperl_mgv_require_module(pTHX_ modperl_mgv_t *symbol,
+ server_rec *s, apr_pool_t *p)
+{
+ char *package =
+ modperl_mgv_as_string(aTHX_ symbol, p, 1);
+
+ if (modperl_require_module(aTHX_ package)) {
+ MP_TRACE_h(MP_FUNC, "reloaded %s for server %s\n",
+ package, modperl_server_desc(s, p));
+ return TRUE;
+ }
+
+ return FALSE;
+}
+#endif
+
/* precompute the hash(es) for handler names */
static void modperl_hash_handlers(pTHX_ apr_pool_t *p, server_rec *s,
- MpAV *entry)
+ MpAV *entry, void *reload)
{
MP_dSCFG(s);
int i;
@@ -297,7 +346,18 @@
modperl_handler_t *handler = handlers[i];
if (MpHandlerPARSED(handler)) {
- MP_TRACE_h(MP_FUNC, "%s already resolved\n", handler->name);
+#ifdef USE_ITHREADS
+ if (reload && !modperl_mgv_lookup(aTHX_ handler->mgv_cv)) {
+ /*
+ * this VirtualHost has its own parent interpreter
+ * must require the module again with this server's THX
+ */
+ modperl_mgv_require_module(aTHX_ handler->mgv_cv,
+ s, p);
+ }
+#endif
+ MP_TRACE_h(MP_FUNC, "%s already resolved in server %s\n",
+ handler->name, modperl_server_desc(s, p));
}
else {
if (MpSrvAUTOLOAD(scfg)) {
@@ -324,7 +384,7 @@
}
for (i=0; i < MP_PER_DIR_NUM_HANDLERS; i++) {
- modperl_hash_handlers(aTHX_ p, s, dir_cfg->handlers[i]);
+ modperl_hash_handlers(aTHX_ p, s, dir_cfg->handlers[i], data);
}
return 1;
@@ -339,22 +399,22 @@
for (i=0; i < MP_PER_SRV_NUM_HANDLERS; i++) {
modperl_hash_handlers(aTHX_ p, s,
- scfg->handlers[i]);
+ scfg->handlers[i], data);
}
for (i=0; i < MP_PROCESS_NUM_HANDLERS; i++) {
modperl_hash_handlers(aTHX_ p, s,
- scfg->process_cfg->handlers[i]);
+ scfg->process_cfg->handlers[i], data);
}
for (i=0; i < MP_CONNECTION_NUM_HANDLERS; i++) {
modperl_hash_handlers(aTHX_ p, s,
- scfg->connection_cfg->handlers[i]);
+ scfg->connection_cfg->handlers[i], data);
}
for (i=0; i < MP_FILES_NUM_HANDLERS; i++) {
modperl_hash_handlers(aTHX_ p, s,
- scfg->files_cfg->handlers[i]);
+ scfg->files_cfg->handlers[i], data);
}
return 1;
@@ -365,4 +425,21 @@
ap_pcw_walk_config(p, s, &perl_module, NULL,
modperl_dw_hash_handlers,
modperl_sw_hash_handlers);
+
+#ifdef USE_ITHREADS
+ /* check for parent interpreters in virtual hosts who need modules
+ * loaded in their own namespace
+ */
+ for (s=s->next; s; s=s->next) {
+ MP_dSCFG(s);
+
+ if (!MpSrvPARENT(scfg) || !MpSrvAUTOLOAD(scfg)) {
+ continue;
+ }
+
+ ap_pcw_walk_config(p, s, &perl_module, (void*)TRUE,
+ modperl_dw_hash_handlers,
+ modperl_sw_hash_handlers);
+ }
+#endif
}
1.2 +9 -1 modperl-2.0/src/modules/perl/modperl_mgv.h
Index: modperl_mgv.h
===================================================================
RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_mgv.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- modperl_mgv.h 2001/03/09 23:42:04 1.1
+++ modperl_mgv.h 2001/03/15 05:39:07 1.2
@@ -7,6 +7,9 @@
GV *modperl_mgv_lookup(pTHX_ modperl_mgv_t *symbol);
+GV *modperl_mgv_lookup_autoload(pTHX_ modperl_mgv_t *symbol,
+ server_rec *s, apr_pool_t *p);
+
int modperl_mgv_resolve(pTHX_ modperl_handler_t *handler,
apr_pool_t *p, const char *name);
@@ -14,7 +17,12 @@
const char *name);
char *modperl_mgv_as_string(pTHX_ modperl_mgv_t *symbol,
- apr_pool_t *p);
+ apr_pool_t *p, int package);
+
+#ifdef USE_ITHREADS
+int modperl_mgv_require_module(pTHX_ modperl_mgv_t *symbol,
+ server_rec *s, apr_pool_t *p);
+#endif
void modperl_mgv_hash_handlers(apr_pool_t *p, server_rec *s);