]> granicus.if.org Git - apache/commitdiff
Generalized the recent prep_walk_cache optimizations to allow other
authorBrian Pane <brianp@apache.org>
Tue, 1 Jan 2002 20:36:18 +0000 (20:36 +0000)
committerBrian Pane <brianp@apache.org>
Tue, 1 Jan 2002 20:36:18 +0000 (20:36 +0000)
modules to register "notes" within the array of working data in
the core_request_config

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@92697 13f79535-47bb-0310-9956-ffa450edef68

include/http_core.h
server/core.c
server/request.c

index 2c8bfb8525e1f896d8b03b898c1dcd05c285208d..7220f2d7cf219afb55fd35f9e79e001ae2b37c09 100644 (file)
@@ -330,23 +330,53 @@ AP_DECLARE_DATA extern module core_module;
 
 /* Per-request configuration */
 
-typedef enum {
-    AP_WALK_DIRECTORY,
-    AP_WALK_LOCATION,
-    AP_WALK_FILE,
-    AP_NUM_WALK_CACHES
-} ap_walk_cache_type;
-
 typedef struct {
     /* bucket brigade used by getline for look-ahead and 
      * ap_get_client_block for holding left-over request body */
     struct apr_bucket_brigade *bb;
 
-    /* a place to hold per-request working data for
-     * ap_directory_walk, ap_location_walk, and ap_file_walk */
-    void *walk_cache[AP_NUM_WALK_CACHES];
+    /* an array of per-request working data elements, accessed
+     * by ID using ap_get_request_note()
+     * (Use ap_register_request_note() during initialization
+     * to add elements)
+     */
+    void **notes;
 } core_request_config;
 
+/* Standard entries that are guaranteed to be accessible via
+ * ap_get_request_note() for each request (additional entries
+ * can be added with ap_register_request_note())
+ */
+#define AP_NOTE_DIRECTORY_WALK 0
+#define AP_NOTE_LOCATION_WALK  1
+#define AP_NOTE_FILE_WALK      2
+#define AP_NUM_STD_NOTES       3
+
+/**
+ * Reserve an element in the core_request_config->notes array
+ * for some application-specific data
+ * @return An integer key that can be passed to ap_get_request_note()
+ *         during request processing to access this element for the
+ *         current request.
+ */
+AP_DECLARE(apr_size_t) ap_register_request_note(void);
+
+/**
+ * Retrieve a pointer to an element in the core_request_config->notes array
+ * @param r The request
+ * @param note_num  A key for the element: either a value obtained from
+ *        ap_register_request_note() or one of the predefined AP_NOTE_*
+ *        values.
+ * @return NULL if the note_num is invalid, otherwise a pointer to the
+ *         requested note element.
+ * @remark At the start of a request, each note element is NULL.  The
+ *         handle provided by ap_get_request_note() is a pointer-to-pointer
+ *         so that the caller can point the element to some app-specific
+ *         data structure.  The caller should guarantee that any such
+ *         structure will last as long as the request itself.
+ */
+AP_DECLARE(void **) ap_get_request_note(request_rec *r, apr_size_t note_num);
+
 /* Per-directory configuration */
 
 typedef unsigned char allow_options_t;
index c3924d5d08c446c4529f079e5127c997aedf9598..39ea6552db8544cc508f034da7850a4022c8eeb3 100644 (file)
@@ -62,6 +62,7 @@
 #include "apr_fnmatch.h"
 #include "apr_hash.h"
 #include "apr_thread_proc.h"    /* for RLIMIT stuff */
+#include "apr_hooks.h"
 
 #define APR_WANT_IOVEC
 #define APR_WANT_STRFUNC
@@ -3383,11 +3384,44 @@ static void core_insert_filter(request_rec *r)
     }
 }
 
+static apr_size_t num_request_notes = AP_NUM_STD_NOTES;
+
+static apr_status_t reset_request_notes(void *dummy)
+{
+    num_request_notes = AP_NUM_STD_NOTES;
+    return APR_SUCCESS;
+}
+
+AP_DECLARE(apr_size_t) ap_register_request_note(void)
+{
+    apr_pool_cleanup_register(apr_global_hook_pool, NULL, reset_request_notes,
+                              apr_pool_cleanup_null);
+    return num_request_notes++;
+}
+
+AP_DECLARE(void **) ap_get_request_note(request_rec *r, apr_size_t note_num)
+{
+    core_request_config *req_cfg;
+    if (note_num >= num_request_notes) {
+        return NULL;
+    }
+    req_cfg = (core_request_config *)
+        ap_get_module_config(r->request_config, &core_module);
+    if (!req_cfg) {
+        return NULL;
+    }
+    return &(req_cfg->notes[note_num]);
+}
+
 static int core_create_req(request_rec *r)
 {
+    /* Alloc the config struct and the array of request notes in
+     * a single block for efficiency
+     */
     core_request_config *req_cfg;
-    req_cfg = apr_palloc(r->pool, sizeof(core_request_config));
-    memset(req_cfg, 0, sizeof(*req_cfg));
+    req_cfg = apr_pcalloc(r->pool, sizeof(core_request_config) +
+                          sizeof(void *) * num_request_notes);
+    req_cfg->notes = (void **)((char *)req_cfg + sizeof(core_request_config));
     if (r->main) {
         core_request_config *main_req_cfg = (core_request_config *)
             ap_get_module_config(r->main->request_config, &core_module);
index dd35e88c1997ecb06b43d4990b96377e5db42a67..381390878af738a72fb36cf5fc289dbeb05e064c 100644 (file)
@@ -296,10 +296,10 @@ typedef struct walk_cache_t {
     apr_array_header_t *walked;         /* The list of walk_walked_t results */
 } walk_cache_t;
 
-static walk_cache_t *prep_walk_cache(ap_walk_cache_type t, request_rec *r)
+static walk_cache_t *prep_walk_cache(apr_size_t t, request_rec *r)
 {
     walk_cache_t *cache;
-    core_request_config *my_req_cfg;
+    void **note;
 
     /* Find the most relevant, recent entry to work from.  That would be
      * this request (on the second call), or the parent request of a
@@ -307,20 +307,19 @@ static walk_cache_t *prep_walk_cache(ap_walk_cache_type t, request_rec *r)
      * this _walk()er with a copy it is allowed to munge.  If there is no
      * parent or prior cached request, then create a new walk cache.
      */
-    my_req_cfg = (core_request_config *)
-        ap_get_module_config(r->request_config, &core_module);
-
-    if (!my_req_cfg || !(cache = my_req_cfg->walk_cache[t])) {
-        core_request_config *req_cfg;
+    note = ap_get_request_note(r, t);
+    if (!note) {
+        return NULL;
+    }
+    if (!(cache = *note)) {
+        void **inherit_note;
         if ((r->main &&
-             (req_cfg = (core_request_config *)
-              ap_get_module_config(r->main->request_config, &core_module)) &&
-             req_cfg->walk_cache[t]) ||
+             ((inherit_note = ap_get_request_note(r->main, t))) &&
+             *inherit_note) ||
             (r->prev &&
-             (req_cfg = (core_request_config *)
-              ap_get_module_config(r->prev->request_config, &core_module)) &&
-             req_cfg->walk_cache[t])) {
-            cache = apr_pmemdup(r->pool, req_cfg->walk_cache[t],
+             ((inherit_note = ap_get_request_note(r->prev, t))) &&
+             *inherit_note)) {
+            cache = apr_pmemdup(r->pool, *inherit_note,
                                 sizeof(*cache));
             cache->walked = apr_array_copy(r->pool, cache->walked);
         }
@@ -328,9 +327,7 @@ static walk_cache_t *prep_walk_cache(ap_walk_cache_type t, request_rec *r)
             cache = apr_pcalloc(r->pool, sizeof(*cache));
             cache->walked = apr_array_make(r->pool, 4, sizeof(walk_walked_t));
         }
-        if (my_req_cfg) {
-            my_req_cfg->walk_cache[t] = cache;
-        }
+        *note = cache;
     }
     return cache;
 }
@@ -489,7 +486,7 @@ AP_DECLARE(int) ap_directory_walk(request_rec *r)
      */
     r->filename = entry_dir;
 
-    cache = prep_walk_cache(AP_WALK_DIRECTORY, r);
+    cache = prep_walk_cache(AP_NOTE_DIRECTORY_WALK, r);
 
     /* If this is not a dirent subrequest with a preconstructed 
      * r->finfo value, then we can simply stat the filename to
@@ -1063,7 +1060,7 @@ AP_DECLARE(int) ap_location_walk(request_rec *r)
     walk_cache_t *cache;
     const char *entry_uri;
 
-    cache = prep_walk_cache(AP_WALK_LOCATION, r);
+    cache = prep_walk_cache(AP_NOTE_LOCATION_WALK, r);
     
     /* No tricks here, there are no <Locations > to parse in this vhost.
      * We won't destroy the cache, just in case _this_ redirect is later
@@ -1219,7 +1216,7 @@ AP_DECLARE(int) ap_file_walk(request_rec *r)
         return OK;
     }
 
-    cache = prep_walk_cache(AP_WALK_FILE, r);
+    cache = prep_walk_cache(AP_NOTE_FILE_WALK, r);
 
     /* No tricks here, there are just no <Files > to parse in this context.
      * We won't destroy the cache, just in case _this_ redirect is later