[svn:mod_parrot] r437 - mod_parrot/branches/hll-modules/src

[email protected] Fri, 19 Sep 2008 14:46:43 -0700 (PDT)
Newsgroups perl.cvs.mod_parrot
Message-ID <[email protected]>
Author: jhorwitz
Date: Fri Sep 19 14:46:42 2008
New Revision: 437

Modified:
   mod_parrot/branches/hll-modules/src/mod_parrot.c

Log:
fix segfault in cleanup handlers


Modified: mod_parrot/branches/hll-modules/src/mod_parrot.c
==============================================================================
--- mod_parrot/branches/hll-modules/src/mod_parrot.c	(original)
+++ mod_parrot/branches/hll-modules/src/mod_parrot.c	Fri Sep 19 14:46:42 2008
@@ -41,9 +41,6 @@
 /* declare our module */
 extern module AP_MODULE_DECLARE_DATA parrot_module;
 
-/* we need to forward declare this */
-static apr_status_t modparrot_request_cleanup(void *data);
-
 /* XXX mod_parrot can crash on x86_64 w/o this.
  * there's no prototype in the standard parrot includes, so compiler assumes
  * return type of 'int', and sizeof(int) != sizeof(pointer) on x86_64.
@@ -303,6 +300,57 @@
     return DECLINED;
 }
 
+/* not a true handler since it has no hook */
+static int modparrot_meta_cleanup_handler(request_rec *r)
+{
+    modparrot_context *ctxp;
+    modparrot_srv_config *mpcfg;
+    module *modp;
+    modparrot_module_info *minfo;
+    Parrot_PMC sub;
+    int status, m;
+
+    /* initialize context */
+    if (!(ctxp = init_ctx(r->server))) {
+        MPLOG_ERROR(r->server, "context initialization failed");
+        return HTTP_INTERNAL_SERVER_ERROR;
+    }
+
+    /* get next module in line -- count backwards since cleanups are LIFO */
+    m = ctxp->module_index--;
+    if (m < 0) return HTTP_INTERNAL_SERVER_ERROR;
+
+    /* decline if mod_parrot isn't enabled  */
+    mpcfg = ap_get_module_config(r->server->module_config, &parrot_module);
+    if (!(mpcfg->option_flags & MP_OPT_ENABLE)) return DECLINED;
+
+    ctxp->r = r;
+
+    /* get HLL config */
+    modp = ((module **)mpcfg->module_array->elts)[m];
+    minfo = (modparrot_module_info *)modp->dynamic_load_handle;
+    /* call meta handler */
+    if (!modparrot_call_meta_handler(ctxp->interp, minfo->namespace,
+       "cleanup_handler", &status)) {
+        MPLOG_ERRORF(r->server, "no cleanup metahandler found for module '%s'",
+            modp->name);
+        status = HTTP_INTERNAL_SERVER_ERROR;
+    }
+
+    /* clean up */
+    release_ctx(ctxp);
+
+    /* tell apache we're done */
+    return status;
+}
+
+static apr_status_t modparrot_meta_request_cleanup(void *data)
+{
+    request_rec *r = (request_rec *)data;
+    modparrot_meta_cleanup_handler(r);
+    return APR_SUCCESS;
+}
+
 #define MP_REQUEST_METAHANDLER(hname, register_cleanup) \
     int modparrot_meta_##hname(request_rec *r) \
     { \
@@ -325,12 +373,12 @@
             &parrot_module); \
         if (!(mpcfg->option_flags & MP_OPT_ENABLE)) return DECLINED; \
         /* take this opportunity to register the mod_parrot cleanup handler \
-         * here, \
-         * as we may not handle any other part of the request until then. \
+         * here, as we may not handle any other part of the request until
+         * then. \
          */ \
         if (register_cleanup) { \
-            apr_pool_cleanup_register(r->pool, r, modparrot_request_cleanup, \
-                apr_pool_cleanup_null); \
+            apr_pool_cleanup_register(r->pool, r, \
+                modparrot_meta_request_cleanup, apr_pool_cleanup_null); \
         } \
         ctxp->r = r; \
         /* XXX register cleanup handler here or in the meta handler? */ \
@@ -357,9 +405,9 @@
         return status; \
     }
 
-MP_REQUEST_METAHANDLER(map_to_storage_handler, 1)
+MP_REQUEST_METAHANDLER(post_read_request_handler, 1)
+MP_REQUEST_METAHANDLER(map_to_storage_handler, 0)
 MP_REQUEST_METAHANDLER(trans_handler, 0)
-MP_REQUEST_METAHANDLER(post_read_request_handler, 0)
 MP_REQUEST_METAHANDLER(header_parser_handler, 0)
 MP_REQUEST_METAHANDLER(access_handler, 0)
 MP_REQUEST_METAHANDLER(authen_handler, 0)
@@ -715,56 +763,6 @@
     return status;
 }
 
-/* not a true handler since it has no hook */
-static int modparrot_cleanup_handler(request_rec *r)
-{
-    modparrot_context *ctxp;
-    modparrot_srv_config *mpcfg;
-    module *modp;
-    modparrot_module_info *minfo;
-    Parrot_PMC sub;
-    int status;
-
-    /* initialize context */
-    if (!(ctxp = init_ctx(r->server))) {
-        MPLOG_ERROR(r->server, "context initialization failed");
-        return HTTP_INTERNAL_SERVER_ERROR;
-    }
-
-    /* get next module in line */
-    ctxp->module_index++;
-
-    /* decline if mod_parrot isn't enabled  */
-    mpcfg = ap_get_module_config(r->server->module_config, &parrot_module);
-    if (!(mpcfg->option_flags & MP_OPT_ENABLE)) return DECLINED;
-
-    ctxp->r = r;
-
-    /* get HLL config */
-    modp = ((module **)mpcfg->module_array->elts)[ctxp->module_index];
-    minfo = (modparrot_module_info *)modp->dynamic_load_handle;
-    /* call meta handler */
-    if (!modparrot_call_meta_handler(ctxp->interp, minfo->namespace,
-       "cleanup_handler", &status)) {
-        MPLOG_ERRORF(r->server, "no cleanup metahandler found for module '%s'",
-            modp->name);
-        status = HTTP_INTERNAL_SERVER_ERROR;
-    }
-
-    /* clean up */
-    release_ctx(ctxp);
-
-    /* tell apache we're done */
-    return status;
-}
-
-static apr_status_t modparrot_request_cleanup(void *data)
-{
-    request_rec *r = (request_rec *)data;
-    modparrot_cleanup_handler(r);
-    return APR_SUCCESS;
-}
-
 static void register_hooks(apr_pool_t *p)
 {
     /* this allows <IfDefine MODPARROT> blocks */