[svn:mod_parrot] r301 - in mod_parrot/trunk: include src

[email protected]
Newsgroups perl.cvs.mod_parrot
Message-ID <[email protected]>
Author: jhorwitz
Date: Fri Dec 28 09:47:11 2007
New Revision: 301

Modified:
   mod_parrot/trunk/include/mod_parrot.h
   mod_parrot/trunk/include/modparrot_config.h
   mod_parrot/trunk/src/context.c
   mod_parrot/trunk/src/mod_parrot.c
   mod_parrot/trunk/src/modparrot_config.c

Log:
properly merge server configs


Modified: mod_parrot/trunk/include/mod_parrot.h
==============================================================================
--- mod_parrot/trunk/include/mod_parrot.h	(original)
+++ mod_parrot/trunk/include/mod_parrot.h	Fri Dec 28 09:47:11 2007
@@ -37,10 +37,11 @@
 /* per-interpreter context */
 struct modparrot_context
 {
-    Parrot_Interp interp;      /* Parrot interpreter */
-    long count;                /* number of interpreter invocations */
-    int locked;                /* 0=available, 1=in use */
-    request_rec *r;            /* request_rec structure for this request */
+    Parrot_Interp interp;        /* this context's interpreter */
+    Parrot_Interp parent_interp; /* parent interpreter */
+    long count;                  /* number of interpreter invocations */
+    int locked;                  /* 0=available, 1=in use */
+    request_rec *r;              /* request_rec structure for this request */
     apr_pool_t *pconf;
     apr_pool_t *plog;
     apr_pool_t *ptemp;
@@ -61,7 +62,7 @@
 char *modparrot_backtrace(Parrot_Interp);
 int modparrot_hll_handler(Parrot_Interp, char *, char *, char *, int *);
 Parrot_PMC get_sub_pmc(Parrot_Interp , char *, char *);
-apr_array_header_t *mp_ctx_pool_init(apr_pool_t *, int);
+apr_array_header_t *mp_ctx_pool_init(apr_pool_t *, Parrot_Interp, int);
 void mp_ctx_pool_destroy(apr_array_header_t *);
 modparrot_context *reserve_ctx(apr_array_header_t *);
 void release_ctx(modparrot_context *);

Modified: mod_parrot/trunk/include/modparrot_config.h
==============================================================================
--- mod_parrot/trunk/include/modparrot_config.h	(original)
+++ mod_parrot/trunk/include/modparrot_config.h	Fri Dec 28 09:47:11 2007
@@ -34,6 +34,8 @@
     apr_array_header_t *ctx_pool;
     char *init_path;
     int trace_flags;
+    int enable_option_flags;
+    int disable_option_flags;
     int option_flags;
     char *include_path;
     apr_array_header_t *preload;
@@ -72,6 +74,7 @@
 void *create_modparrot_srv_config(apr_pool_t *, server_rec *);
 void *create_modparrot_dir_config(apr_pool_t *, char *path);
 void *merge_modparrot_dir_config(apr_pool_t *, void *, void *);
+void *merge_modparrot_srv_config(apr_pool_t *, void *, void *);
 
 /* handler directives */
 const char *modparrot_cmd_open_logs_handler(cmd_parms *, void *, const char *);

Modified: mod_parrot/trunk/src/context.c
==============================================================================
--- mod_parrot/trunk/src/context.c	(original)
+++ mod_parrot/trunk/src/context.c	Fri Dec 28 09:47:11 2007
@@ -33,18 +33,21 @@
 #include "modparrot_config.h"
 
 /* initialize pool of contexts */
-apr_array_header_t * mp_ctx_pool_init(apr_pool_t *p, int num)
+apr_array_header_t * mp_ctx_pool_init(apr_pool_t *p,
+    Parrot_Interp parent_interp, int num)
 {
     int i;
     apr_array_header_t *ctx_pool;
+    modparrot_context *ctx;
 
     if (!(ctx_pool = apr_array_make(p, num, sizeof(modparrot_context)))) {
         return NULL;
     }
 
     for (i = 0; i < num; i++) {
-        *(modparrot_context **)apr_array_push(ctx_pool) =
-            (modparrot_context *)apr_pcalloc(p, sizeof(modparrot_context));
+        ctx = (*(modparrot_context **)apr_array_push(ctx_pool) =
+            (modparrot_context *)apr_pcalloc(p, sizeof(modparrot_context)));
+        ctx->parent_interp = parent_interp;
     }
 
     return ctx_pool;

Modified: mod_parrot/trunk/src/mod_parrot.c
==============================================================================
--- mod_parrot/trunk/src/mod_parrot.c	(original)
+++ mod_parrot/trunk/src/mod_parrot.c	Fri Dec 28 09:47:11 2007
@@ -55,27 +55,25 @@
     modparrot_srv_config *cfg;
 
     cfg = ap_get_module_config(s->module_config, &parrot_module);
+    if (cfg->trace_flags == -1) cfg->trace_flags = 0;
 
     /* initialize interpreter */
-    interp = modparrot_init_interpreter(NULL);
+    interp = modparrot_init_interpreter(ctx->parent_interp);
     Parrot_set_trace(interp, cfg->trace_flags);
 
-    /* run initialization code */
-    if (cfg->init_path) {
-
-        /* load the init code */
-        modparrot_load_bytecode(interp, cfg->init_path);
-
-        /* set additional include paths from apache config */
-        if (cfg->include_path) {
-            modparrot_call_sub_IS(interp, "_modparrot",
-                "modparrot_set_include_path", &i, cfg->include_path);
-        }
-
-        /* initialize parrot side */
-        modparrot_call_sub(interp, "_modparrot", "modparrot_init");
+    /* load the init code */
+    modparrot_load_bytecode(interp,
+        cfg->init_path ? cfg->init_path : MODPARROT_DEFAULT_INIT);
+
+    /* set additional include paths from apache config */
+    if (cfg->include_path) {
+        modparrot_call_sub_IS(interp, "_modparrot",
+            "modparrot_set_include_path", &i, cfg->include_path);
     }
 
+    /* initialize parrot side */
+    modparrot_call_sub(interp, "_modparrot", "modparrot_init");
+
     /* set our context
      * Since there is a one-to-one relationship between threads and
      * interpreters, we can store our context as a global in each interpreter.
@@ -837,7 +835,7 @@
     apr_pool_t *ptemp, server_rec *s)
 {
     modparrot_srv_config *cfg;
-    modparrot_context *ctxp, *vsctxp;
+    modparrot_context *ctxp;
     int handler_status;
     char *sub, *hll;
     server_rec *vs;
@@ -846,7 +844,7 @@
     cfg = ap_get_module_config(s->module_config, &parrot_module);
 
     /* ALWAYS INIT THE CONTEXT POOL AND START THE INTERPRETER HERE! */
-    if (!(cfg->ctx_pool = mp_ctx_pool_init(pconf, 1))) {
+    if (!(cfg->ctx_pool = mp_ctx_pool_init(pconf, NULL, 1))) {
         MPLOG_ERROR(s, "context pool creation failed");
         return HTTP_INTERNAL_SERVER_ERROR;
     }
@@ -855,17 +853,18 @@
         return HTTP_INTERNAL_SERVER_ERROR;
     }
 
-    ctxp->pconf = pconf;
-    ctxp->plog = plog;
-    ctxp->ptemp = ptemp;
-    ctxp->s = s;
-
     /* init per-server (MP_OPT_PARENT) or per-process (default) pools */
     for (vs = s->next; vs; vs = vs->next) {
         modparrot_srv_config *vscfg;
+        modparrot_context *vsctxp;
         vscfg = ap_get_module_config(vs->module_config, &parrot_module);
-        if (vscfg->option_flags | MP_OPT_PARENT) {
-            if (!(vscfg->ctx_pool = mp_ctx_pool_init(pconf, 1))) {
+        if (vscfg->option_flags & MP_OPT_PARENT) {
+            /* XXX this crashes if we don't specify parent context. we can't
+             * create multiple interpreters in the same process, which is a
+             * either a problem with parrot or a problem with my understanding
+             * of the interpreter creation process.
+             */
+            if (!(vscfg->ctx_pool = mp_ctx_pool_init(pconf, ctxp->interp, 1))) {
                 MPLOG_ERROR(s, "context pool creation failed");
                 return HTTP_INTERNAL_SERVER_ERROR;
             }
@@ -877,10 +876,6 @@
         else {
             vscfg->ctx_pool = cfg->ctx_pool;
         }
-        vsctxp->pconf = pconf;
-        vsctxp->plog = plog;
-        vsctxp->ptemp = ptemp;
-        vsctxp->s = vs;
     }
 
     /* if not our handler, return OK (open_logs must return OK) */
@@ -888,6 +883,11 @@
         return OK;
     }
 
+    ctxp->pconf = pconf;
+    ctxp->plog = plog;
+    ctxp->ptemp = ptemp;
+    ctxp->s = s;
+
     /* call HLL handler */
     sub = "open_logs_handler";
     hll = cfg->open_logs_handler->hll ?  cfg->open_logs_handler->hll : "PIR";
@@ -1176,7 +1176,7 @@
     create_modparrot_dir_config,
     NULL, /* merge_modparrot_dir_config, */
     create_modparrot_srv_config,
-    NULL,
+    merge_modparrot_srv_config,
     modparrot_cmds,
     register_hooks
 };

Modified: mod_parrot/trunk/src/modparrot_config.c
==============================================================================
--- mod_parrot/trunk/src/modparrot_config.c	(original)
+++ mod_parrot/trunk/src/modparrot_config.c	Fri Dec 28 09:47:11 2007
@@ -54,9 +54,11 @@
 
     cfg = (modparrot_srv_config *)apr_pcalloc(p, sizeof(modparrot_srv_config));
     cfg->pool = p;
-    cfg->trace_flags = 0;
-    cfg->option_flags = 0;
-    cfg->init_path = MODPARROT_DEFAULT_INIT;
+    cfg->trace_flags = -1; /* -1 == unspecified */
+    cfg->enable_option_flags = 0; /* only used during configuration merge */
+    cfg->disable_option_flags = 0; /* only used during configuration merge */
+    cfg->option_flags = 0; /* use this after configuration is merged */
+    cfg->init_path = NULL;
     cfg->preload = apr_array_make(p, 2, sizeof(modparrot_handler_info));
     cfg->include_path = NULL;
     cfg->type_map = apr_table_make(p, 2);
@@ -71,6 +73,62 @@
     return (void *)cfg;
 }
 
+void *merge_modparrot_srv_config(apr_pool_t *p, void *base, void *new)
+{
+    modparrot_srv_config *basecfg = (modparrot_srv_config *)base;
+    modparrot_srv_config *newcfg = (modparrot_srv_config *)new;
+    modparrot_srv_config *merged = (modparrot_srv_config *)
+        apr_pcalloc(p, sizeof(modparrot_srv_config));
+
+    /* create base config options from enable & disable flags */
+    basecfg->option_flags |= basecfg->enable_option_flags;
+    basecfg->option_flags &= ~(basecfg->disable_option_flags);
+
+    /* create new config options from enable & disable flags */
+    newcfg->option_flags |= newcfg->enable_option_flags;
+    newcfg->option_flags &= ~(newcfg->disable_option_flags);
+
+    /* merge options first since we make decisions based on them */
+    if (newcfg->option_flags & MP_OPT_PARENT) {
+        merged->option_flags = newcfg->option_flags;
+    }
+    else {
+        merged->option_flags = basecfg->option_flags;
+        merged->option_flags |= newcfg->enable_option_flags;
+        merged->option_flags &= ~(newcfg->disable_option_flags);
+    }
+
+    /* merge type and handler maps */
+    merged->type_map = apr_table_copy(p, basecfg->type_map);
+    apr_table_overlap(merged->type_map, newcfg->type_map,
+        APR_OVERLAP_TABLES_SET);
+    merged->handler_map = apr_table_copy(p, basecfg->handler_map);
+    apr_table_overlap(merged->handler_map, newcfg->handler_map,
+        APR_OVERLAP_TABLES_SET);
+
+    /* merges specific to the Parent option */
+    if (newcfg->option_flags & MP_OPT_PARENT) {
+        merged->include_path = newcfg->include_path ?
+            newcfg->include_path : basecfg->include_path;
+        merged->trace_flags = newcfg->trace_flags;
+        merged->init_path = newcfg->init_path;
+        merged->preload = apr_array_copy(p, newcfg->preload);
+    }
+    else {
+        /* just override the scalars */
+        merged->init_path = newcfg->init_path ?
+            newcfg->init_path : basecfg->init_path;
+        merged->trace_flags = (newcfg->trace_flags != -1) ?
+            newcfg->trace_flags : basecfg->trace_flags;
+
+        /* but concat the arrays */
+        merged->preload = apr_array_copy(p, basecfg->preload);
+        apr_array_cat(merged->preload, newcfg->preload);
+    }
+
+    return (void *)merged;
+}
+
 void *create_modparrot_dir_config(apr_pool_t *p, char *path)
 {
     modparrot_dir_config *cfg;
@@ -174,8 +232,12 @@
  */
 int modparrot_set_option(modparrot_srv_config *cfg, char *option, int enable)
 {
+    int *flags;
+
+    flags = enable ? &(cfg->enable_option_flags) : &(cfg->disable_option_flags);
+
     if (!strncasecmp(option, "Parent", 6)) {
-        cfg->option_flags &= enable ? MP_OPT_PARENT : ~MP_OPT_PARENT;
+        *flags |= MP_OPT_PARENT;
     }
     else {
         return 0;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.