Stefan Fuhrmann <[email protected]> writes:
> Thanks, it would be nice if could do something within Subversion because
> httpd and apr patches may take a while to trickle down into releases.
> Meanwhile, I posted a patch for mod_dav on the httpd dev list.
I took a look at what's happening, and I think the root cause of the problem
is that during a PROPFIND walk, we use the request pool for allocations that
happen per every walked entry. This occurs when mod_dav_svn/repos.c:do_walk()
calls dav_propfind_walker() with dav_walk_resource.pool pointing to the request
pool.
Here is what we could do about it:
(1) PROPFIND walker in do_walk() could use an iterpool when preparing the
dav_walk_resource for dav_propfind_walker().
(2) The mod_dav's dav_open_propdb() function could use resource->pool when
creating the subpool. In this particular case, it's not necessary to
solve the long-standing problem with the lifetime of that subpool, and,
since opening a propdb requires a dav_resource, doing so wouldn't violate
propdb's lifetime guarantees.
I prepared two patches that target mod_dav and mod_dav_svn. Together, they
solve the memory usage problem in my experiments.
I plan on posting the patch for mod_dav to the corresponding thread [1] in
<[email protected]> — hopefully, tomorrow.
[1]
https://mail-archives.apache.org/mod_mbox/httpd-dev/201512.mbox/%3C5678958E.20608%40apache.org%3E
Regards,
Evgeny Kotkov
Index: modules/dav/main/props.c
===================================================================
--- modules/dav/main/props.c (revision 1721415)
+++ modules/dav/main/props.c (working copy)
@@ -524,7 +524,7 @@ DAV_DECLARE(dav_error *)dav_open_propdb(request_re
apr_array_header_t * ns_xlate,
dav_propdb **p_propdb)
{
- dav_propdb *propdb = apr_pcalloc(r->pool, sizeof(*propdb));
+ dav_propdb *propdb = apr_pcalloc(resource->pool, sizeof(*propdb));
*p_propdb = NULL;
@@ -537,7 +537,7 @@ DAV_DECLARE(dav_error *)dav_open_propdb(request_re
#endif
propdb->r = r;
- apr_pool_create(&propdb->p, r->pool);
+ apr_pool_create(&propdb->p, resource->pool);
propdb->resource = resource;
propdb->ns_xlate = ns_xlate;
Index: subversion/mod_dav_svn/repos.c
===================================================================
--- subversion/mod_dav_svn/repos.c (revision 1721415)
+++ subversion/mod_dav_svn/repos.c (working copy)
@@ -4335,6 +4335,9 @@ do_walk(walker_ctx_t *ctx,
and this is the invocation for the collection. Alternatively, this is
the first [and only] entry to do_walk() for a member resource, so
this will be the invocation for the member. */
+ ctx->wres.pool = scratch_pool;
+ ctx->res.pool = scratch_pool;
+
err = (*params->func)(&ctx->wres,
isdir ? DAV_CALLTYPE_COLLECTION : DAV_CALLTYPE_MEMBER);
if (err != NULL)
@@ -4445,6 +4448,9 @@ do_walk(walker_ctx_t *ctx,
if (dirent->kind == svn_node_file)
{
+ ctx->wres.pool = iterpool;
+ ctx->res.pool = iterpool;
+
err = (*params->func)(&ctx->wres, DAV_CALLTYPE_MEMBER);
if (err != NULL)
{