On Tuesday, April 12, 2011 18:24:28 William A. Rowe Jr. wrote:
> Suggestion - an EXEC_ON_READ 'DynamicModulesMax' directive, which would
> let us conf_vector_length = total_modules + dyn_modules_max; after the
> read_config, and finally lock down conf_vector_length = total_modules;
> at the end of post_config.  WDYT?

The attached patch implements the DynamicModulesMax directive. It can appear 
anywhere in the config file but is best placed *before* any LoadModule 
directive. Up to post_config the number of prelinked modules plus 
DynamicModulesMax is used as conf_vector_length. In core_post_config the 
length is then settled on total_modules.

Torsten Förtsch

-- 
Need professional modperl support? Hire me! (http://foertsch.name)

Like fantasy? http://kabatinte.net
Index: server/config.c
===================================================================
--- server/config.c	(revision 1094174)
+++ server/config.c	(working copy)
@@ -181,22 +181,22 @@
 static int total_modules = 0;
 
 /* dynamic_modules is the number of modules that have been added
- * after the pre-loaded ones have been set up. It shouldn't be larger
- * than DYNAMIC_MODULE_LIMIT.
+ * after the pre-loaded ones have been set up. It should be at most
+ * dynamic_modules_max.
  */
 static int dynamic_modules = 0;
 
-/* The maximum possible value for total_modules, i.e. number of static
- * modules plus DYNAMIC_MODULE_LIMIT.
+/* The maximum possible value for dynamic_modules. Shouldn't be larger than
+ * DYNAMIC_MODULE_LIMIT.
  */
-static int max_modules = 0;
+static int dynamic_modules_max;
 
 /* The number of elements we need to alloc for config vectors. Before loading
- * of dynamic modules, we must be liberal and set this to max_modules. After
- * loading of dynamic modules, we can trim it down to total_modules. On
- * restart, reset to max_modules.
+ * of dynamic modules, we must be liberal and set this to the largest possible
+ * value (number of prelinked modules + dynamic_modules_max). After loading of
+ * dynamic modules, we can trim it down to total_modules.
  */
-static int conf_vector_length = 0;
+static int conf_vector_length;
 
 AP_DECLARE_DATA module *ap_top_module = NULL;
 AP_DECLARE_DATA module **ap_loaded_modules=NULL;
@@ -234,6 +234,22 @@
  * overridden).
  */
 
+AP_DECLARE(void) ap_set_dynamic_modules_max(int lim)
+{
+    dynamic_modules_max = lim;
+    conf_vector_length = dynamic_modules_max + total_modules - dynamic_modules;
+}
+
+AP_DECLARE(int) ap_get_dynamic_modules_max(void)
+{
+    return dynamic_modules_max;
+}
+
+AP_DECLARE(void) ap_settle_module_count(void)
+{
+    conf_vector_length = total_modules;
+}
+
 static ap_conf_vector_t *create_empty_config(apr_pool_t *p)
 {
     void *conf_vector = apr_pcalloc(p, sizeof(void *) * conf_vector_length);
@@ -542,7 +558,7 @@
     }
 
     if (m->module_index == -1) {
-        if (dynamic_modules >= DYNAMIC_MODULE_LIMIT) {
+        if (dynamic_modules >= dynamic_modules_max) {
             return apr_psprintf(p, "Module \"%s\" could not be loaded, "
                                 "because the dynamic module limit was "
                                 "reached. Please increase "
@@ -740,8 +756,7 @@
     for (m = ap_preloaded_modules; *m != NULL; m++)
         (*m)->module_index = total_modules++;
 
-    max_modules = total_modules + DYNAMIC_MODULE_LIMIT + 1;
-    conf_vector_length = max_modules;
+    ap_set_dynamic_modules_max(DYNAMIC_MODULE_LIMIT);
 
     /*
      *  Initialise list of loaded modules and short names
@@ -2255,12 +2270,6 @@
 }
 
 
-static apr_status_t reset_conf_vector_length(void *dummy)
-{
-    conf_vector_length = max_modules;
-    return APR_SUCCESS;
-}
-
 AP_DECLARE(server_rec*) ap_read_config(process_rec *process, apr_pool_t *ptemp,
                                        const char *filename,
                                        ap_directive_t **conftree)
@@ -2272,6 +2281,7 @@
         return s;
     }
 
+    ap_set_dynamic_modules_max(DYNAMIC_MODULE_LIMIT);
     init_config_globals(p);
 
     /* All server-wide config files now have the SAME syntax... */
@@ -2309,14 +2319,6 @@
         return NULL;
     }
 
-    /*
-     * We have loaded the dynamic modules. From now on we know exactly how
-     * long the config vectors need to be.
-     */
-    conf_vector_length = total_modules;
-    apr_pool_cleanup_register(p, NULL, reset_conf_vector_length,
-                              apr_pool_cleanup_null);
-
     error = process_command_config(s, ap_server_post_read_config, conftree,
                                    p, ptemp);
 
Index: server/core.c
===================================================================
--- server/core.c	(revision 1094174)
+++ server/core.c	(working copy)
@@ -3167,6 +3167,19 @@
 }
 #endif
 
+static const char *set_dynamic_modules_max(cmd_parms *cmd, void *dummy,
+					   const char *arg)
+{
+    const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
+
+    if (err != NULL) {
+        return err;
+    }
+
+    ap_set_dynamic_modules_max(atoi(arg));
+    return NULL;
+}
+
 #ifdef RLIMIT_CPU
 static const char *set_limit_cpu(cmd_parms *cmd, void *conf_,
                                  const char *arg, const char *arg2)
@@ -3753,6 +3766,9 @@
               "body"),
 AP_INIT_RAW_ARGS("Mutex", ap_set_mutex, NULL, RSRC_CONF,
                  "mutex (or \"default\") and mechanism"),
+AP_INIT_TAKE1("DynamicModulesMax", set_dynamic_modules_max, NULL,
+	      RSRC_CONF | EXEC_ON_READ,
+	      "Limit on the number of dynamically loadable modules"),
 
 /* System Resource Controls */
 #ifdef RLIMIT_CPU
@@ -4175,6 +4191,12 @@
                      "or other system security module is loaded.");
         return !OK;
     }
+
+    /*
+     * We have loaded the dynamic modules. From now on we know exactly how
+     * long the config vectors need to be.
+     */
+    ap_settle_module_count();
     return OK;
 }
 
Index: modules/core/mod_so.c
===================================================================
--- modules/core/mod_so.c	(revision 1094174)
+++ modules/core/mod_so.c	(working copy)
@@ -113,8 +113,6 @@
     so_server_conf *soc;
 
     soc = (so_server_conf *)apr_pcalloc(p, sizeof(so_server_conf));
-    soc->loaded_modules = apr_array_make(p, DYNAMIC_MODULE_LIMIT,
-                                     sizeof(ap_module_symbol_t));
 
     return (void *)soc;
 }
@@ -179,6 +177,13 @@
      */
     sconf = (so_server_conf *)ap_get_module_config(cmd->server->module_config,
                                                 &so_module);
+
+    if (!sconf->loaded_modules) {
+	sconf->loaded_modules = apr_array_make(cmd->pool,
+					       ap_get_dynamic_modules_max(),
+					       sizeof(ap_module_symbol_t));
+    }
+
     modie = (ap_module_symbol_t *)sconf->loaded_modules->elts;
     for (i = 0; i < sconf->loaded_modules->nelts; i++) {
         modi = &modie[i];
@@ -339,13 +344,15 @@
 
     sconf = (so_server_conf *)ap_get_module_config(s->module_config,
                                                    &so_module);
-    modie = (ap_module_symbol_t *)sconf->loaded_modules->elts;
+    if (sconf->loaded_modules) {
+        modie = (ap_module_symbol_t *)sconf->loaded_modules->elts;
 
-    for (i = 0; i < sconf->loaded_modules->nelts; i++) {
-        modi = &modie[i];
-        if (modi->name != NULL && strcmp(modi->name, modname) == 0) {
-            return modi->modp;
-        }
+	for (i = 0; i < sconf->loaded_modules->nelts; i++) {
+	    modi = &modie[i];
+	    if (modi->name != NULL && strcmp(modi->name, modname) == 0) {
+	        return modi->modp;
+	    }
+	}
     }
     return NULL;
 }
@@ -378,12 +385,14 @@
         }
     }
 
-    modie = (ap_module_symbol_t *)sconf->loaded_modules->elts;
-    for (i = 0; i < sconf->loaded_modules->nelts; i++) {
-        modi = &modie[i];
-        if (modi->name != NULL) {
-            apr_file_printf(out, " %s (shared)\n", modi->name);
-        }
+    if (sconf->loaded_modules) {
+        modie = (ap_module_symbol_t *)sconf->loaded_modules->elts;
+	for (i = 0; i < sconf->loaded_modules->nelts; i++) {
+	    modi = &modie[i];
+	      if (modi->name != NULL) {
+		  apr_file_printf(out, " %s (shared)\n", modi->name);
+	      }
+	}
     }
 }
 
Index: modules/generators/mod_cgid.c
===================================================================
--- modules/generators/mod_cgid.c	(revision 1094174)
+++ modules/generators/mod_cgid.c	(working copy)
@@ -421,7 +421,7 @@
     }
 
     /* handle module indexes and such */
-    rconf = (void **) apr_pcalloc(r->pool, sizeof(void *) * (total_modules + DYNAMIC_MODULE_LIMIT));
+    rconf = (void **)ap_create_request_config(r->pool);
 
     temp_core = (core_request_config *)apr_palloc(r->pool, sizeof(core_module));
     rconf[req->core_module_index] = (void *)temp_core;
Index: include/http_config.h
===================================================================
--- include/http_config.h	(revision 1094174)
+++ include/http_config.h	(working copy)
@@ -472,6 +472,25 @@
 typedef struct ap_conf_vector_t ap_conf_vector_t;
 
 /**
+ * Set the dynamic module limit. Used by the DynamicModulesMax directive.
+ * Also adjusts conf_vector_length.
+ * @param lim The limit.
+ */
+AP_DECLARE(void) ap_set_dynamic_modules_max(int lim);
+
+/**
+ * Get the dynamic module limit.
+ * @return The limit.
+ */
+AP_DECLARE(int) ap_get_dynamic_modules_max(void);
+
+/**
+ * When the number of modules has settled (in post_config) this function
+ * adjusts the conf_vector_length.
+ */
+AP_DECLARE(void) ap_settle_module_count(void);
+
+/**
  * Generic accessors for other modules to get at their own module-specific
  * data
  * @param cv The vector in which the modules configuration is stored.

Reply via email to