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

[email protected] Sat, 7 Feb 2009 13:05:19 -0800 (PST)
Newsgroups perl.cvs.mod_parrot
Message-ID <[email protected]>
Author: jhorwitz
Date: Sat Feb  7 13:05:14 2009
New Revision: 607

Modified:
   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:
named context pools part 3 (still needs context affinity for threaded MPMs)


Modified: mod_parrot/trunk/include/modparrot_config.h
==============================================================================
--- mod_parrot/trunk/include/modparrot_config.h	(original)
+++ mod_parrot/trunk/include/modparrot_config.h	Sat Feb  7 13:05:14 2009
@@ -103,6 +103,8 @@
 {
     char *name;
     modparrot_module_info *minfo;
+    const char *ctx_pool_name; /* context pool name for this config */
+    apr_array_header_t *ctx_pool; /* cached pointer to the context pool */
     Parrot_PMC cfg;
 };
 typedef struct modparrot_module_config modparrot_module_config;

Modified: mod_parrot/trunk/src/context.c
==============================================================================
--- mod_parrot/trunk/src/context.c	(original)
+++ mod_parrot/trunk/src/context.c	Sat Feb  7 13:05:14 2009
@@ -100,6 +100,27 @@
     /* apache will take care of destroying the actual context pool array */
 }
 
+/* destroy all context pools */
+void mp_ctx_pool_destroy_all(void)
+{
+    apr_pool_t *p;
+    apr_hash_index_t *idx;
+    char *name = NULL;
+
+    apr_pool_create(&p, NULL);
+
+    for (idx = apr_hash_first(p, mp_globals.ctx_pool_hash); idx;
+        idx = apr_hash_next(idx)) {
+        const void *key;
+        apr_ssize_t klen;
+        void *val;
+        apr_hash_this(idx, &key, &klen, &val);
+        mp_ctx_pool_destroy((apr_array_header_t *)val);
+    }
+
+    apr_pool_destroy(p);
+}
+
 /* finds and reserves a context for use by a handler */
 modparrot_context *reserve_ctx(apr_array_header_t *ctx_pool, int index)
 {

Modified: mod_parrot/trunk/src/mod_parrot.c
==============================================================================
--- mod_parrot/trunk/src/mod_parrot.c	(original)
+++ mod_parrot/trunk/src/mod_parrot.c	Sat Feb  7 13:05:14 2009
@@ -173,6 +173,34 @@
     return(interp);
 }
 
+static apr_array_header_t *select_ctx_pool(module *modp, server_rec *s,
+    ap_conf_vector_t *per_dir_config)
+{
+    modparrot_module_config *cfg;
+    modparrot_module_info *minfo = modp->dynamic_load_handle;
+
+    /* try section scope first */
+    if (per_dir_config) {
+        cfg = ap_get_module_config(per_dir_config, modp);
+        if (cfg) {
+            if (cfg->ctx_pool) {
+                return(cfg->ctx_pool);
+            }
+        }
+    }
+
+    /* now try server scope */
+    cfg = ap_get_module_config(s->module_config, modp);
+    if (cfg) {
+        if (cfg->ctx_pool) {
+            return(cfg->ctx_pool);
+        }
+    }
+
+    /* fall back to the module's default pool */
+    return(minfo->ctx_pool);
+}
+
 static modparrot_context *init_ctx(server_rec *s, apr_pool_t *p,
     apr_array_header_t *ctx_pool)
 {
@@ -223,6 +251,38 @@
     return(ctxp);
 }
 
+static modparrot_context *clone_ctx_state(modparrot_context *cur_ctxp,
+    apr_array_header_t *new_ctx_pool, server_rec *s, apr_pool_t *p)
+{
+    modparrot_context *ctxp;
+
+    /* don't clone from same pool, just return current context */
+    if (cur_ctxp->ctx_pool == new_ctx_pool) return cur_ctxp;
+
+    /* grab a context from the requested pool */
+    if (!(ctxp = init_ctx(s, p, new_ctx_pool))) {
+        MPLOG_ERROR(s, "context initialization failed");
+        return NULL;
+    }
+
+    MP_TRACE_c(s, "cloning context %p -> %p", cur_ctxp, ctxp);
+
+    /* copy relevant cached data from current context */
+    ctxp->r = cur_ctxp->r;
+    ctxp->s = cur_ctxp->s;
+    ctxp->pconf = cur_ctxp->pconf;
+    ctxp->plog = cur_ctxp->plog;
+    ctxp->ptemp = cur_ctxp->ptemp;
+    ctxp->pchild = cur_ctxp->pchild;
+    ctxp->c = cur_ctxp->c;
+    ctxp->csd = cur_ctxp->csd;
+    ctxp->module_index = cur_ctxp->module_index;
+
+    /* NOTE: caller must release the old context */
+
+    return(ctxp);
+}
+
 /* public interface for starting an interpreter */
 modparrot_context *modparrot_startup(apr_pool_t *p, server_rec *s,
     Parrot_Interp parent_interp, const char *pool_name)
@@ -422,6 +482,8 @@
         /* get next module in line */ \
         if (!(mpcfg->option_flags & MP_OPT_ENABLE)) return DECLINED; \
         modp = NEXT_HANDLER_MODULE(henum); \
+        ctxp = clone_ctx_state(ctxp, select_ctx_pool(modp, r->server, NULL), \
+            r->server, r->pool); \
         /* take this opportunity to register the request cleanup handler \
          * here, as we may not handle any other part of the request until \
          * then. NOTE: this is mod_parrot internal only and NOT for HLLs. \
@@ -489,6 +551,9 @@
     /* get next module in line */
     modp = NEXT_HANDLER_MODULE(MP_HOOK_PRE_CONNECTION);
 
+    ctxp = clone_ctx_state(ctxp, select_ctx_pool(modp, c->base_server, NULL),
+        c->base_server, c->pool);
+
     ctxp->c = c;
     ctxp->csd = csd;
 
@@ -553,6 +618,9 @@
     /* get next module in line */
     modp = NEXT_HANDLER_MODULE(MP_HOOK_PROCESS_CONNECTION);
 
+    ctxp = clone_ctx_state(ctxp, select_ctx_pool(modp, c->base_server, NULL),
+        c->base_server, c->pool);
+
     ctxp->c = c;
 
     /* get HLL config */
@@ -626,6 +694,8 @@
     /* get next module in line */
     modp = NEXT_HANDLER_MODULE(MP_HOOK_CHILD_INIT);
 
+    ctxp = clone_ctx_state(ctxp, select_ctx_pool(modp, s, NULL), s, p);
+
     ctxp->pchild = p;
     ctxp->s = s;
 
@@ -693,6 +763,8 @@
     /* get next module in line */
     modp = NEXT_HANDLER_MODULE(MP_HOOK_POST_CONFIG);
 
+    ctxp = clone_ctx_state(ctxp, select_ctx_pool(modp, s, NULL), s, ptemp);
+
     ctxp->pconf = pconf;
     ctxp->plog = plog;
     ctxp->ptemp = ptemp;
@@ -792,6 +864,7 @@
 int modparrot_meta_open_logs_handler(apr_pool_t *pconf,
     apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
 {
+    apr_array_header_t *ctx_pool;
     modparrot_context *ctxp;
     modparrot_srv_config *mpcfg;
     module *modp;
@@ -807,13 +880,15 @@
         return HTTP_INTERNAL_SERVER_ERROR;
     }
 
+    /* get next module in line */
+    modp = NEXT_HANDLER_MODULE(MP_HOOK_OPEN_LOGS);
+
+    ctxp = clone_ctx_state(ctxp, select_ctx_pool(modp, s, NULL), s, ptemp);
+
     /* decline if mod_parrot isn't enabled -- but open_logs must return OK */
     mpcfg = ap_get_module_config(s->module_config, &parrot_module);
     if (!(mpcfg->option_flags & MP_OPT_ENABLE)) return OK;
 
-    /* get next module in line */
-    modp = NEXT_HANDLER_MODULE(MP_HOOK_OPEN_LOGS);
-
     ctxp->pconf = pconf;
     ctxp->plog = plog;
     ctxp->ptemp = ptemp;

Modified: mod_parrot/trunk/src/modparrot_config.c
==============================================================================
--- mod_parrot/trunk/src/modparrot_config.c	(original)
+++ mod_parrot/trunk/src/modparrot_config.c	Sat Feb  7 13:05:14 2009
@@ -52,7 +52,7 @@
     cfg = ap_get_module_config(s->module_config, &parrot_module);
 
     /* destroy context pools and interpreters */
-    mp_ctx_pool_destroy(cfg->ctx_pool);
+    mp_ctx_pool_destroy_all();
     cfg->ctx_pool = NULL;
     mp_globals.is_started = 0;