Hi All,
Attached patch fixes the File descriptor leaks in ra_serf's way of
driving the destination delta editor with *LONG* living pools.
This patch fixes it.
I think similar stuff needs to be done for a case of directory having
lots of subdirectories.
All tests pass over ra_serf... I am just posting here just in case
somebody has some opinions.
If there are no objections I will commit tomorrow my time.
With regards
Kamesh Jayachandran
Fix for issue3870 "File descriptor leaks during svnsync".
Before this fix, all of destination delta editor's interfaces
are called with *LONG* living pool(dst_rev_pool living for one full revision).
This makes it a memory bloat and bloat of other OS resources like
file descriptors to live as long the dst_rev_pool.
* subversion/libsvn_ra_serf/replay.c
(replay_context_t.file_pool): New pool of file scope.
(start_replay): clear the file_pool.
Use file_pool for dest editor's file operations.
(end_replay): Use file_pool for dest editor's file operations.
(svn_ra_serf__replay, svn_ra_serf__replay_range):
Create a new pool 'replay_ctx->file_pool'.
* subversion/tests/cmdline/svnsync_tests.py
(fd_leak_sync_from_serf_to_local): Remove XFail marker.
Patch by: kameshj
Arwin Arni <arwin{_AT_}collab.net>
Index: subversion/libsvn_ra_serf/replay.c
===================================================================
--- subversion/libsvn_ra_serf/replay.c (revision 1102326)
+++ subversion/libsvn_ra_serf/replay.c (working copy)
@@ -93,6 +93,8 @@
typedef struct replay_context_t {
apr_pool_t *src_rev_pool;
apr_pool_t *dst_rev_pool;
+ /*file_pool is cleared after completion of each file. */
+ apr_pool_t *file_pool;
/* Are we done fetching this file? */
svn_boolean_t done;
@@ -336,6 +338,7 @@
const char *file_name, *rev;
replay_info_t *info;
+ svn_pool_clear(ctx->file_pool);
file_name = svn_xml_get_attr_value("name", attrs);
if (!file_name)
{
@@ -353,7 +356,7 @@
SVN_ERR(ctx->editor->open_file(file_name, info->parent->baton,
SVN_STR_TO_REV(rev),
- ctx->dst_rev_pool, &info->baton));
+ ctx->file_pool, &info->baton));
}
else if ((state == OPEN_DIR || state == ADD_DIR) &&
strcmp(name.name, "add-file") == 0)
@@ -362,6 +365,7 @@
svn_revnum_t rev;
replay_info_t *info;
+ svn_pool_clear(ctx->file_pool);
file_name = svn_xml_get_attr_value("name", attrs);
if (!file_name)
{
@@ -380,7 +384,7 @@
SVN_ERR(ctx->editor->add_file(file_name, info->parent->baton,
copyfrom, rev,
- ctx->dst_rev_pool, &info->baton));
+ ctx->file_pool, &info->baton));
}
else if ((state == OPEN_FILE || state == ADD_FILE) &&
strcmp(name.name, "apply-textdelta") == 0)
@@ -400,7 +404,7 @@
}
SVN_ERR(ctx->editor->apply_textdelta(info->baton, checksum,
- info->pool,
+ ctx->file_pool,
&textdelta,
&textdelta_baton));
@@ -417,7 +421,7 @@
checksum = svn_xml_get_attr_value("checksum", attrs);
SVN_ERR(ctx->editor->close_file(info->baton, checksum,
- ctx->dst_rev_pool));
+ ctx->file_pool));
svn_ra_serf__xml_pop_state(parser);
}
@@ -439,7 +443,6 @@
info = push_state(parser, ctx, CHANGE_PROP);
- info->name = apr_pstrdup(ctx->dst_rev_pool, prop_name);
if (svn_xml_get_attr_value("del", attrs))
info->del_prop = TRUE;
@@ -447,9 +450,15 @@
info->del_prop = FALSE;
if (state == OPEN_FILE || state == ADD_FILE)
- info->change = ctx->editor->change_file_prop;
+ {
+ info->name = apr_pstrdup(ctx->file_pool, prop_name);
+ info->change = ctx->editor->change_file_prop;
+ }
else
- info->change = ctx->editor->change_dir_prop;
+ {
+ info->name = apr_pstrdup(ctx->dst_rev_pool, prop_name);
+ info->change = ctx->editor->change_dir_prop;
+ }
}
@@ -527,7 +536,10 @@
tmp_prop.data = info->data;
tmp_prop.len = info->len;
- prop_val = svn_base64_decode_string(&tmp_prop, ctx->dst_rev_pool);
+ if (strcmp(name.name, "change-file-prop") == 0)
+ prop_val = svn_base64_decode_string(&tmp_prop, ctx->file_pool);
+ else
+ prop_val = svn_base64_decode_string(&tmp_prop, ctx->dst_rev_pool);
}
SVN_ERR(info->change(info->parent->baton, info->name, prop_val,
@@ -635,6 +647,7 @@
replay_ctx = apr_pcalloc(pool, sizeof(*replay_ctx));
replay_ctx->src_rev_pool = pool;
+ replay_ctx->file_pool = svn_pool_create(pool);
replay_ctx->editor = editor;
replay_ctx->editor_baton = edit_baton;
replay_ctx->done = FALSE;
@@ -751,6 +764,7 @@
replay_ctx = apr_pcalloc(ctx_pool, sizeof(*replay_ctx));
replay_ctx->src_rev_pool = ctx_pool;
+ replay_ctx->file_pool = svn_pool_create(pool);
replay_ctx->revstart_func = revstart_func;
replay_ctx->revfinish_func = revfinish_func;
replay_ctx->replay_baton = replay_baton;
Index: subversion/tests/cmdline/svnsync_tests.py
===================================================================
--- subversion/tests/cmdline/svnsync_tests.py (revision 1102326)
+++ subversion/tests/cmdline/svnsync_tests.py (working copy)
@@ -946,7 +946,6 @@
@Issue(3870)
@SkipUnless(svntest.main.is_posix_os)
-@XFail(svntest.main.is_ra_type_dav_serf)
def fd_leak_sync_from_serf_to_local(sbox):
"fd leak during sync from serf to local"
import resource