From: Ruediger Pluem Date: Tue, 18 Sep 2018 12:58:57 +0000 (+0000) Subject: * Doing a PROPFIND on a large collection e.g. 50.000 elements can easily X-Git-Tag: 2.5.0-alpha2-ci-test-only~2333 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4a374968a656854e9bd68cad6b20a4037bf5714c;p=thirdparty%2Fapache%2Fhttpd.git * Doing a PROPFIND on a large collection e.g. 50.000 elements can easily 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 --- diff --git a/modules/dav/main/props.c b/modules/dav/main/props.c index 792c87db8be..3b95dc4ed2a 100644 --- a/modules/dav/main/props.c +++ b/modules/dav/main/props.c @@ -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;