]> granicus.if.org Git - apache/commitdiff
* Doing a PROPFIND on a large collection e.g. 50.000 elements can easily
authorRuediger Pluem <rpluem@apache.org>
Tue, 18 Sep 2018 12:58:57 +0000 (12:58 +0000)
committerRuediger Pluem <rpluem@apache.org>
Tue, 18 Sep 2018 12:58:57 +0000 (12:58 +0000)
  consume 1 GB of memory as the subrequests and propdb pools are not
  destroyed and cleared after each element was handled.
  Do this now. There is one case in dav_get_props where elem->priv
  lives longer then the propdb pool. In this case allocate from r->pool.
  Furthermore also recycle propdb's which allows to clear the propdb's
  pools instead of destroying them and creating them again.

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

modules/dav/main/props.c

index 792c87db8be06d69ef75ed76f050d1469fd89265..3b95dc4ed2a84654f4e4d650cad70f567a52448b 100644 (file)
@@ -524,7 +524,21 @@ DAV_DECLARE(dav_error *)dav_open_propdb(request_rec *r, dav_lockdb *lockdb,
                                         apr_array_header_t * ns_xlate,
                                         dav_propdb **p_propdb)
 {
-    dav_propdb *propdb = apr_pcalloc(r->pool, sizeof(*propdb));
+    dav_propdb *propdb = NULL;
+    /*
+     * Check if we have tucked away a previous propdb and reuse it.
+     * Otherwise create a new one and tuck it away
+     */
+    apr_pool_userdata_get((void **)&propdb, "propdb", r->pool);
+    if (!propdb) {
+        propdb = apr_pcalloc(r->pool, sizeof(*propdb));
+        apr_pool_userdata_setn(propdb, "propdb", NULL, r->pool);
+        apr_pool_create(&propdb->p, r->pool);
+    }
+    else {
+        /* Play safe and clear the pool of the reused probdb */
+        apr_pool_clear(propdb->p);
+    }
 
     *p_propdb = NULL;
 
@@ -537,7 +551,6 @@ DAV_DECLARE(dav_error *)dav_open_propdb(request_rec *r, dav_lockdb *lockdb,
 #endif
 
     propdb->r = r;
-    apr_pool_create(&propdb->p, r->pool);
     propdb->resource = resource;
     propdb->ns_xlate = ns_xlate;
 
@@ -562,10 +575,12 @@ DAV_DECLARE(void) dav_close_propdb(dav_propdb *propdb)
         (*propdb->db_hooks->close)(propdb->db);
     }
 
-    /* Currently, mod_dav's pool usage doesn't allow clearing this pool. */
-#if 0
-    apr_pool_destroy(propdb->p);
-#endif
+    if (propdb->subreq) {
+        ap_destroy_sub_req(propdb->subreq);
+        propdb->subreq = NULL;
+    }
+
+    apr_pool_clear(propdb->p);
 }
 
 DAV_DECLARE(dav_get_props_result) dav_get_allprops(dav_propdb *propdb,
@@ -815,7 +830,8 @@ DAV_DECLARE(dav_get_props_result) dav_get_props(dav_propdb *propdb,
         */
 
         if (elem->priv == NULL) {
-            elem->priv = apr_pcalloc(propdb->p, sizeof(*priv));
+            /* elem->priv outlives propdb->p. Hence use the request pool */
+            elem->priv = apr_pcalloc(propdb->r->pool, sizeof(*priv));
         }
         priv = elem->priv;