Author: brane
Date: Sun Jan 25 02:17:46 2026
New Revision: 1931527
Log:
On the better-pristines branch: Add an optional callback to spillbufs to
customize how the spill file is created.
* subversion/include/private/svn_subr_private.h
(svn_spillbuf__create_file_t): New callback type.
(svn_spillbuf__set_spill_cb): New prototype.
* subversion/libsvn_subr/spillbuf.c: Include svn_error.h.
(svn_spillbuf_t::create_spill_file): New struct member.
(svn_spillbuf__create_extended): Initialize this struct member.
(svn_spillbuf__set_spill_cb): Implement.
(svn_spillbuf__write): Call the file creation callback.
* subversion/tests/libsvn_subr/spillbuf-test.c: Inlcude svn_io.h.
(test_spillbuf__file_attrs): Verify that the spill file is deleted
when it's closed. This is behaviour is specific to the test.
(create_spillbuf_file): Spillbuf file creation callback.
(test_spillbuf_file_attrs_spill_callback): New test. Use the callback
to create a file with delete-on-close behaviour even when the
spillbuf was created without that flag.
(test_funcs): Register test_spillbuf_file_attrs_spill_callback.
Modified:
subversion/branches/better-pristines/subversion/include/private/svn_subr_private.h
subversion/branches/better-pristines/subversion/libsvn_subr/spillbuf.c
subversion/branches/better-pristines/subversion/tests/libsvn_subr/spillbuf-test.c
Modified:
subversion/branches/better-pristines/subversion/include/private/svn_subr_private.h
==============================================================================
---
subversion/branches/better-pristines/subversion/include/private/svn_subr_private.h
Sun Jan 25 00:07:00 2026 (r1931526)
+++
subversion/branches/better-pristines/subversion/include/private/svn_subr_private.h
Sun Jan 25 02:17:46 2026 (r1931527)
@@ -118,7 +118,27 @@ svn_spillbuf__create(apr_size_t blocksiz
apr_size_t maxsize,
apr_pool_t *result_pool);
-/* Determine how much content is stored in the spill buffer. */
+/* Callback for creating the spillbuf's spill file.
+ The prototype is the same as for svn_io_open_unique_file3(). */
+typedef svn_error_t *(*svn_spillbuf__create_file_t)(
+ apr_file_t **file,
+ const char **temp_path,
+ const char *dirpath,
+ svn_io_file_del_t delete_when,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/* Set a callback that will be called to create the spillbuf's spill file.
+ A default implemntation will be used if this callback is not set.
+ NOTE: Calling this function after the spill file has been created is
+ a programming error and will cause an assertion. It's best to
+ set the callback when the spillbuf is created and before the
+ first write. */
+svn_error_t *
+svn_spillbuf__set_spill_cb(svn_spillbuf_t *buf,
+ svn_spillbuf__create_file_t create_spill_file);
+
+/* Determine how much content is stored in the spill buffer. */
svn_filesize_t
svn_spillbuf__get_size(const svn_spillbuf_t *buf);
Modified: subversion/branches/better-pristines/subversion/libsvn_subr/spillbuf.c
==============================================================================
--- subversion/branches/better-pristines/subversion/libsvn_subr/spillbuf.c
Sun Jan 25 00:07:00 2026 (r1931526)
+++ subversion/branches/better-pristines/subversion/libsvn_subr/spillbuf.c
Sun Jan 25 02:17:46 2026 (r1931527)
@@ -23,6 +23,7 @@
#include <apr_file_io.h>
+#include "svn_error.h"
#include "svn_io.h"
#include "svn_pools.h"
@@ -80,6 +81,9 @@ struct svn_spillbuf_t {
/* The name of the temporary spill file. */
const char *filename;
+ /* The callback that creates the spill file, see above. */
+ svn_spillbuf__create_file_t create_spill_file;
+
/* When false, do not delete the spill file when it is closed. */
svn_boolean_t delete_on_close;
@@ -123,9 +127,10 @@ svn_spillbuf__create_extended(apr_size_t
buf->pool = result_pool;
buf->blocksize = blocksize;
buf->maxsize = maxsize;
+ buf->dirpath = dirpath;
+ buf->create_spill_file = svn_io_open_unique_file3;
buf->delete_on_close = 0 != (flags & SVN_SPILLBUF__DELETE_ON_CLOSE);
buf->spill_all_contents = 0 != (flags & SVN_SPILLBUF__SPILL_ALL_CONTENTS);
- buf->dirpath = dirpath;
return buf;
}
@@ -141,6 +146,15 @@ svn_spillbuf__create(apr_size_t blocksiz
result_pool);
}
+svn_error_t *
+svn_spillbuf__set_spill_cb(svn_spillbuf_t *buf,
+ svn_spillbuf__create_file_t create_spill_file)
+{
+ SVN_ERR_ASSERT(!buf->spill && !buf->filename);
+ buf->create_spill_file = create_spill_file;
+ return SVN_NO_ERROR;
+}
+
svn_filesize_t
svn_spillbuf__get_size(const svn_spillbuf_t *buf)
{
@@ -215,13 +229,13 @@ svn_spillbuf__write(svn_spillbuf_t *buf,
if (buf->spill == NULL
&& ((buf->maxsize - buf->memory_size) < len))
{
- SVN_ERR(svn_io_open_unique_file3(&buf->spill,
- &buf->filename,
- buf->dirpath,
- (buf->delete_on_close
- ? svn_io_file_del_on_close
- : svn_io_file_del_none),
- buf->pool, scratch_pool));
+ SVN_ERR(buf->create_spill_file(&buf->spill,
+ &buf->filename,
+ buf->dirpath,
+ (buf->delete_on_close
+ ? svn_io_file_del_on_close
+ : svn_io_file_del_none),
+ buf->pool, scratch_pool));
/* Optionally write the memory contents into the file. */
if (buf->spill_all_contents)
Modified:
subversion/branches/better-pristines/subversion/tests/libsvn_subr/spillbuf-test.c
==============================================================================
---
subversion/branches/better-pristines/subversion/tests/libsvn_subr/spillbuf-test.c
Sun Jan 25 00:07:00 2026 (r1931526)
+++
subversion/branches/better-pristines/subversion/tests/libsvn_subr/spillbuf-test.c
Sun Jan 25 02:17:46 2026 (r1931527)
@@ -21,6 +21,7 @@
* ====================================================================
*/
+#include "svn_io.h"
#include "svn_types.h"
#include "private/svn_subr_private.h"
@@ -518,6 +519,8 @@ test_spillbuf__file_attrs(apr_pool_t *po
svn_spillbuf_t *buf)
{
svn_filesize_t filesize;
+ svn_node_kind_t kind;
+ const char *path;
SVN_ERR(svn_spillbuf__write(buf, "abcdef", 6, pool));
SVN_ERR(svn_spillbuf__write(buf, "ghijkl", 6, pool));
@@ -537,6 +540,15 @@ test_spillbuf__file_attrs(apr_pool_t *po
else
SVN_TEST_ASSERT(filesize == (svn_spillbuf__get_size(buf)
- svn_spillbuf__get_memory_size(buf)));
+
+ /* The file must not exist after it is closed. */
+ path = svn_spillbuf__get_filename(buf);
+ SVN_ERR(svn_io_check_path(path, &kind, pool));
+ SVN_TEST_ASSERT(kind == svn_node_file);
+ SVN_ERR(svn_io_file_close(svn_spillbuf__get_file(buf), pool));
+ SVN_ERR(svn_io_check_path(path, &kind, pool));
+ SVN_TEST_ASSERT(kind == svn_node_none);
+
return SVN_NO_ERROR;
}
@@ -561,6 +573,31 @@ test_spillbuf_file_attrs_spill_all(apr_p
return test_spillbuf__file_attrs(pool, TRUE, buf);
}
+static svn_error_t *
+create_spillbuf_file(apr_file_t **file,
+ const char **temp_path,
+ const char *dirpath,
+ svn_io_file_del_t delete_when,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ SVN_TEST_ASSERT(delete_when == svn_io_file_del_none);
+ return svn_io_open_unique_file3(file, temp_path, dirpath,
+ svn_io_file_del_on_close,
+ result_pool, scratch_pool);
+}
+
+static svn_error_t *
+test_spillbuf_file_attrs_spill_callback(apr_pool_t *pool)
+{
+ svn_spillbuf_t *buf = svn_spillbuf__create_extended(4 /* blocksize */,
+ 10 /* maxsize */,
+ 0, NULL, pool);
+ svn_spillbuf__set_spill_cb(buf, create_spillbuf_file);
+ return test_spillbuf__file_attrs(pool, FALSE, buf);
+}
+
+
/* The test table. */
static int max_threads = 1;
@@ -592,6 +629,8 @@ static struct svn_test_descriptor_t test
SVN_TEST_PASS2(test_spillbuf_file_attrs, "check spill file properties"),
SVN_TEST_PASS2(test_spillbuf_file_attrs_spill_all,
"check spill file properties (spill-all-data)"),
+ SVN_TEST_PASS2(test_spillbuf_file_attrs_spill_callback,
+ "check spill file properties (custom file)"),
SVN_TEST_NULL
};