Stefan Fuhrmann <stef...@apache.org> 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
<d...@httpd.apache.org> — 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)
             {

Reply via email to