You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2010/09/06 21:13:44 UTC
svn commit: r993127 [4/11] - in /subversion/branches/performance: ./ build/
build/generator/ notes/ notes/tree-conflicts/
subversion/bindings/javahl/native/
subversion/bindings/javahl/src/org/apache/subversion/javahl/
subversion/bindings/javahl/src/org...
Modified: subversion/branches/performance/subversion/libsvn_ra_serf/win32_auth_sspi.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_ra_serf/win32_auth_sspi.c?rev=993127&r1=993126&r2=993127&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_ra_serf/win32_auth_sspi.c (original)
+++ subversion/branches/performance/subversion/libsvn_ra_serf/win32_auth_sspi.c Mon Sep 6 19:13:39 2010
@@ -171,14 +171,18 @@ do_auth(serf_sspi_context_t *sspi_contex
apr_size_t tmp_len, token_len = 0;
const char *space;
- space = strchr(auth_attr, ' ');
- if (space)
+ if (auth_attr != NULL)
{
- const char *base64_token = apr_pstrmemdup(pool,
- auth_attr, space - auth_attr);
- token_len = apr_base64_decode_len(base64_token);
- token = apr_palloc(pool, token_len);
- apr_base64_decode(token, base64_token);
+ space = strchr(auth_attr, ' ');
+ if (space)
+ {
+ const char *base64_token = apr_pstrmemdup(pool,
+ auth_attr,
+ space - auth_attr);
+ token_len = apr_base64_decode_len(base64_token);
+ token = apr_palloc(pool, token_len);
+ apr_base64_decode(token, base64_token);
+ }
}
/* We can get a whole batch of 401 responses from the server, but we should
Modified: subversion/branches/performance/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_ra_svn/client.c?rev=993127&r1=993126&r2=993127&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/branches/performance/subversion/libsvn_ra_svn/client.c Mon Sep 6 19:13:39 2010
@@ -885,8 +885,10 @@ static svn_error_t *ra_svn_end_commit(vo
&(commit_info->author),
&(commit_info->post_commit_err)));
- return ccb->callback(commit_info, ccb->callback_baton, ccb->pool);
+ if (ccb->callback)
+ SVN_ERR(ccb->callback(commit_info, ccb->callback_baton, ccb->pool));
+ return SVN_NO_ERROR;
}
static svn_error_t *ra_svn_commit(svn_ra_session_t *session,
Modified: subversion/branches/performance/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_repos/dump.c?rev=993127&r1=993126&r2=993127&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/performance/subversion/libsvn_repos/dump.c Mon Sep 6 19:13:39 2010
@@ -25,6 +25,7 @@
#include "svn_pools.h"
#include "svn_error.h"
#include "svn_fs.h"
+#include "svn_hash.h"
#include "svn_iter.h"
#include "svn_repos.h"
#include "svn_string.h"
@@ -40,12 +41,6 @@
/*----------------------------------------------------------------------*/
-/** A variant of our hash-writing routine in libsvn_subr; this one
- writes to a stringbuf instead of a file, and outputs PROPS-END
- instead of END. If OLDHASH is not NULL, then only properties
- which vary from OLDHASH will be written, and properties which
- exist only in OLDHASH will be written out with "D" entries
- (like "K" entries but with no corresponding value). **/
static void
write_hash_to_stringbuf(apr_hash_t *hash,
@@ -295,6 +290,53 @@ make_dir_baton(const char *path,
}
+/* For each property in PROPHASH, write headers containing MD5 and SHA1
+ * checksums of property content to STREAM.
+ * Do temporary allocations in SCRATCH_POOL. */
+static svn_error_t *
+write_prop_content_checksums(svn_stream_t *stream,
+ apr_hash_t *prophash,
+ apr_pool_t *scratch_pool)
+{
+ apr_hash_index_t *hi;
+ apr_pool_t *iterpool;
+
+ iterpool = svn_pool_create(scratch_pool);
+ for (hi = apr_hash_first(scratch_pool, prophash);
+ hi;
+ hi = apr_hash_next(hi))
+ {
+ svn_checksum_t *checksum;
+ const char *hex_digest;
+ const char *propname;
+ svn_string_t *propval;
+
+ svn_pool_clear(iterpool);
+
+ propname = svn__apr_hash_index_key(hi);
+ propval = svn__apr_hash_index_val(hi);
+
+ SVN_ERR(svn_checksum(&checksum, svn_checksum_md5,
+ propval->data, propval->len, iterpool));
+ hex_digest = svn_checksum_to_cstring(checksum, iterpool);
+ if (hex_digest)
+ SVN_ERR(svn_stream_printf(stream, iterpool,
+ SVN_REPOS_DUMPFILE_PROP_CONTENT_MD5
+ ": (%s) %s\n", propname, hex_digest));
+ SVN_ERR(svn_checksum(&checksum, svn_checksum_sha1,
+ propval->data, propval->len, iterpool));
+ hex_digest = svn_checksum_to_cstring(checksum, iterpool);
+ if (hex_digest)
+ SVN_ERR(svn_stream_printf(stream, iterpool,
+ SVN_REPOS_DUMPFILE_PROP_CONTENT_SHA1
+ ": (%s) %s\n", propname, hex_digest));
+ }
+ svn_pool_destroy(iterpool);
+
+ return SVN_NO_ERROR;
+}
+
+
/* This helper is the main "meat" of the editor -- it does all the
work of writing a node record.
@@ -509,6 +551,7 @@ dump_node(struct edit_baton *eb,
{
apr_hash_t *prophash, *oldhash = NULL;
apr_size_t proplen;
+ svn_stream_t *propstream;
SVN_ERR(svn_fs_node_proplist(&prophash, eb->fs_root, path, pool));
@@ -559,12 +602,19 @@ dump_node(struct edit_baton *eb,
SVN_REPOS_DUMPFILE_PROP_DELTA
": true\n"));
}
- write_hash_to_stringbuf(prophash, oldhash, &propstring, pool);
+ else
+ oldhash = apr_hash_make(pool);
+ propstring = svn_stringbuf_create_ensure(0, pool);
+ propstream = svn_stream_from_stringbuf(propstring, pool);
+ svn_hash_write_incremental(prophash, oldhash, propstream, "PROPS-END",
+ pool);
+ SVN_ERR(svn_stream_close(propstream));
proplen = propstring->len;
content_length += proplen;
SVN_ERR(svn_stream_printf(eb->stream, pool,
SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH
": %" APR_SIZE_T_FMT "\n", proplen));
+ SVN_ERR(write_prop_content_checksums(eb->stream, prophash, pool));
}
/* If we are supposed to dump text, write out a text length header
@@ -962,6 +1012,7 @@ write_revision_record(svn_stream_t *stre
svn_stringbuf_t *encoded_prophash;
apr_time_t timetemp;
svn_string_t *datevalue;
+ svn_stream_t *propstream;
/* Read the revision props even if we're aren't going to dump
them for verification purposes */
@@ -981,7 +1032,10 @@ write_revision_record(svn_stream_t *stre
datevalue);
}
- write_hash_to_stringbuf(props, NULL, &encoded_prophash, pool);
+ encoded_prophash = svn_stringbuf_create_ensure(0, pool);
+ propstream = svn_stream_from_stringbuf(encoded_prophash, pool);
+ svn_hash_write2(props, propstream, "PROPS-END", pool);
+ SVN_ERR(svn_stream_close(propstream));
/* ### someday write a revision-content-checksum */
@@ -992,6 +1046,7 @@ write_revision_record(svn_stream_t *stre
SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH
": %" APR_SIZE_T_FMT "\n",
encoded_prophash->len));
+ SVN_ERR(write_prop_content_checksums(stream, props, pool));
/* Write out a regular Content-length header for the benefit of
non-Subversion RFC-822 parsers. */
Modified: subversion/branches/performance/subversion/libsvn_repos/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_repos/repos.c?rev=993127&r1=993126&r2=993127&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_repos/repos.c (original)
+++ subversion/branches/performance/subversion/libsvn_repos/repos.c Mon Sep 6 19:13:39 2010
@@ -1806,14 +1806,14 @@ struct hotcopy_ctx_t {
size_t src_len; /* len of the source path*/
};
-/** Called by (svn_io_dir_walk).
+/** Called by (svn_io_dir_walk2).
* Copies the repository structure with exception of @c SVN_REPOS__DB_DIR,
* @c SVN_REPOS__LOCK_DIR and @c SVN_REPOS__FORMAT.
* Those directories and files are handled separetly.
* @a baton is a pointer to (struct hotcopy_ctx_t) specifying
* destination path to copy to and the length of the source path.
*
- * @copydoc svn_io_dir_walk()
+ * @copydoc svn_io_dir_walk2()
*/
static svn_error_t *hotcopy_structure(void *baton,
const char *path,
@@ -1910,11 +1910,11 @@ svn_repos_hotcopy(const char *src_path,
hotcopy_context.dest = dst_path;
hotcopy_context.src_len = strlen(src_path);
- SVN_ERR(svn_io_dir_walk(src_path,
- 0,
- hotcopy_structure,
- &hotcopy_context,
- pool));
+ SVN_ERR(svn_io_dir_walk2(src_path,
+ 0,
+ hotcopy_structure,
+ &hotcopy_context,
+ pool));
/* Prepare dst_repos object so that we may create locks,
so that we may open repository */
Modified: subversion/branches/performance/subversion/libsvn_subr/config_win.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/config_win.c?rev=993127&r1=993126&r2=993127&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/config_win.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/config_win.c Mon Sep 6 19:13:39 2010
@@ -177,7 +177,7 @@ svn_config__parse_registry(svn_config_t
{
return svn_error_createf(SVN_ERR_BAD_FILENAME, NULL,
"Unrecognised registry path '%s'",
- svn_path_local_style(file, pool));
+ svn_dirent_local_style(file, pool));
}
err = RegOpenKeyEx(base_hkey, file, 0,
@@ -189,11 +189,11 @@ svn_config__parse_registry(svn_config_t
if (!is_enoent)
return svn_error_createf(SVN_ERR_BAD_FILENAME, NULL,
"Can't open registry key '%s'",
- svn_path_local_style(file, pool));
+ svn_dirent_local_style(file, pool));
else if (must_exist && is_enoent)
return svn_error_createf(SVN_ERR_BAD_FILENAME, NULL,
"Can't find registry key '%s'",
- svn_path_local_style(file, pool));
+ svn_dirent_local_style(file, pool));
else
return SVN_NO_ERROR;
}
Modified: subversion/branches/performance/subversion/libsvn_subr/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/deprecated.c?rev=993127&r1=993126&r2=993127&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/deprecated.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/deprecated.c Mon Sep 6 19:13:39 2010
@@ -751,6 +751,43 @@ svn_io_get_dirents(apr_hash_t **dirents,
return svn_io_get_dirents2(dirents, path, pool);
}
+struct walk_func_filter_baton_t
+{
+ svn_io_walk_func_t walk_func;
+ void *walk_baton;
+};
+
+/* Implements svn_io_walk_func_t, but only allows APR_DIR and APR_REG
+ finfo types through to the wrapped function/baton. */
+static svn_error_t *
+walk_func_filter_func(void *baton,
+ const char *path,
+ const apr_finfo_t *finfo,
+ apr_pool_t *pool)
+{
+ struct walk_func_filter_baton_t *b = baton;
+
+ if (finfo->filetype == APR_DIR || finfo->filetype == APR_REG)
+ SVN_ERR(b->walk_func(b->walk_baton, path, finfo, pool));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_io_dir_walk(const char *dirname,
+ apr_int32_t wanted,
+ svn_io_walk_func_t walk_func,
+ void *walk_baton,
+ apr_pool_t *pool)
+{
+ struct walk_func_filter_baton_t baton;
+ baton.walk_func = walk_func;
+ baton.walk_baton = walk_baton;
+ return svn_error_return(svn_io_dir_walk2(dirname, wanted,
+ walk_func_filter_func,
+ &baton, pool));
+}
+
svn_error_t *
svn_io_file_read_full(apr_file_t *file, void *buf,
apr_size_t nbytes, apr_size_t *bytes_read,
@@ -759,7 +796,6 @@ svn_io_file_read_full(apr_file_t *file,
return svn_io_file_read_full2(file, buf, nbytes, bytes_read, FALSE, pool);
}
-
/*** From constructors.c ***/
svn_log_changed_path_t *
svn_log_changed_path_dup(const svn_log_changed_path_t *changed_path,
Modified: subversion/branches/performance/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/io.c?rev=993127&r1=993126&r2=993127&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/io.c Mon Sep 6 19:13:39 2010
@@ -2044,44 +2044,8 @@ svn_io_get_dir_filenames(apr_hash_t **di
const char *path,
apr_pool_t *pool)
{
- apr_status_t status;
- apr_dir_t *this_dir;
- apr_finfo_t this_entry;
- apr_int32_t flags = APR_FINFO_NAME;
-
- *dirents = apr_hash_make(pool);
-
- SVN_ERR(svn_io_dir_open(&this_dir, path, pool));
-
- for (status = apr_dir_read(&this_entry, flags, this_dir);
- status == APR_SUCCESS;
- status = apr_dir_read(&this_entry, flags, this_dir))
- {
- if ((this_entry.name[0] == '.')
- && ((this_entry.name[1] == '\0')
- || ((this_entry.name[1] == '.')
- && (this_entry.name[2] == '\0'))))
- {
- continue;
- }
- else
- {
- const char *name;
- SVN_ERR(entry_name_to_utf8(&name, this_entry.name, path, pool));
- apr_hash_set(*dirents, name, APR_HASH_KEY_STRING, name);
- }
- }
-
- if (! (APR_STATUS_IS_ENOENT(status)))
- return svn_error_wrap_apr(status, _("Can't read directory '%s'"),
- svn_dirent_local_style(path, pool));
-
- status = apr_dir_close(this_dir);
- if (status)
- return svn_error_wrap_apr(status, _("Error closing directory '%s'"),
- svn_dirent_local_style(path, pool));
-
- return SVN_NO_ERROR;
+ return svn_error_return(svn_io_get_dirents3(dirents, path, TRUE,
+ pool, pool));
}
svn_io_dirent2_t *
@@ -2764,11 +2728,15 @@ svn_io_detect_mimetype2(const char **mim
/* Right now, this function is going to be really stupid. It's
- going to examine the first block of data, and make sure that 85%
+ going to examine the first block of data, and make sure that 15%
of the bytes are such that their value is in the ranges 0x07-0x0D
- or 0x20-0x7F, and that 100% of those bytes is not 0x00.
+ or 0x20-0x7F, and that none of those bytes is 0x00. If those
+ criteria are not met, we're calling it binary.
- If those criteria are not met, we're calling it binary. */
+ NOTE: Originally, I intended to target 85% of the bytes being in
+ the specified ranges, but I flubbed the condition. At any rate,
+ folks aren't complaining, so I'm not sure that it's worth
+ adjusting this retroactively now. --cmpilato */
if (amt_read > 0)
{
apr_size_t i;
@@ -3338,11 +3306,11 @@ svn_io_dir_read(apr_finfo_t *finfo,
svn_error_t *
-svn_io_dir_walk(const char *dirname,
- apr_int32_t wanted,
- svn_io_walk_func_t walk_func,
- void *walk_baton,
- apr_pool_t *pool)
+svn_io_dir_walk2(const char *dirname,
+ apr_int32_t wanted,
+ svn_io_walk_func_t walk_func,
+ void *walk_baton,
+ apr_pool_t *pool)
{
apr_status_t apr_err;
apr_dir_t *handle;
@@ -3411,11 +3379,11 @@ svn_io_dir_walk(const char *dirname,
SVN_ERR(entry_name_to_utf8(&name_utf8, finfo.name, dirname,
subpool));
full_path = svn_dirent_join(dirname, name_utf8, subpool);
- SVN_ERR(svn_io_dir_walk(full_path,
- wanted,
- walk_func,
- walk_baton,
- subpool));
+ SVN_ERR(svn_io_dir_walk2(full_path,
+ wanted,
+ walk_func,
+ walk_baton,
+ subpool));
}
else if (finfo.filetype == APR_REG || finfo.filetype == APR_LNK)
{
@@ -3429,9 +3397,10 @@ svn_io_dir_walk(const char *dirname,
subpool));
}
/* else:
- some other type of file; skip it.
+ Some other type of file; skip it for now. We've reserved the
+ right to expand our coverage here in the future, though,
+ without revving this API.
*/
-
}
svn_pool_destroy(subpool);
Modified: subversion/branches/performance/subversion/libsvn_subr/opt.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/opt.c?rev=993127&r1=993126&r2=993127&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/opt.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/opt.c Mon Sep 6 19:13:39 2010
@@ -942,12 +942,6 @@ svn_opt__arg_canonicalize_url(const char
/* Auto-escape some ASCII characters. */
target = svn_path_uri_autoescape(target, pool);
- /* The above doesn't guarantee a valid URI. */
- if (! svn_path_is_uri_safe(target))
- return svn_error_createf(SVN_ERR_BAD_URL, 0,
- _("URL '%s' is not properly URI-encoded"),
- target);
-
/* Verify that no backpaths are present in the URL. */
if (svn_path_is_backpath_present(target))
return svn_error_createf(SVN_ERR_BAD_URL, 0,
Modified: subversion/branches/performance/subversion/libsvn_subr/sqlite.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/sqlite.c?rev=993127&r1=993126&r2=993127&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/sqlite.c Mon Sep 6 19:13:39 2010
@@ -81,10 +81,12 @@ struct svn_sqlite__stmt_t
};
-/* Convert SQLite error codes to SVN */
-#define SQLITE_ERROR_CODE(x) ((x) == SQLITE_READONLY \
- ? SVN_ERR_SQLITE_READONLY \
- : SVN_ERR_SQLITE_ERROR )
+/* Convert SQLite error codes to SVN. Evaluates X multiple times */
+#define SQLITE_ERROR_CODE(x) ((x) == SQLITE_READONLY \
+ ? SVN_ERR_SQLITE_READONLY \
+ : ((x) == SQLITE_BUSY \
+ ? SVN_ERR_SQLITE_BUSY \
+ : SVN_ERR_SQLITE_ERROR) )
/* SQLITE->SVN quick error wrap, much like SVN_ERR. */
@@ -174,10 +176,11 @@ step_with_expectation(svn_sqlite__stmt_t
if ((got_row && !expecting_row)
||
(!got_row && expecting_row))
- return svn_error_create(SVN_ERR_SQLITE_ERROR, NULL,
+ return svn_error_create(SVN_ERR_SQLITE_ERROR,
+ svn_sqlite__reset(stmt),
expecting_row
- ? _("Expected database row missing")
- : _("Extra database row found"));
+ ? _("Expected database row missing")
+ : _("Extra database row found"));
return SVN_NO_ERROR;
}
@@ -965,8 +968,50 @@ svn_sqlite__with_transaction(svn_sqlite_
/* Commit or rollback the sqlite transaction. */
if (err)
{
- svn_error_clear(exec_sql(db, "ROLLBACK TRANSACTION;"));
- return svn_error_return(err);
+ svn_error_t *err2 = exec_sql(db, "ROLLBACK TRANSACTION;");
+
+ if (err2 && err2->apr_err == SVN_ERR_SQLITE_BUSY)
+ {
+ int i;
+ /* ### Houston, we have a problem!
+
+ We are trying to rollback but we can't because some
+ statements are still busy. This leaves the database
+ unusable for future transactions as the current transaction
+ is still open.
+
+ As we are returning the actual error as the most relevant
+ error in the chain, our caller might assume that it can
+ retry/compensate on this error (e.g. SVN_WC_LOCKED), while
+ in fact the SQLite database is unusable until the statements
+ started within this transaction are reset and the transaction
+ aborted.
+
+ We try to compensate by resetting al prepared but unreset
+ statements; but we leave the busy error in the chain anyway to
+ help diagnosing the original error and help in finding where
+ a reset statement is missing. */
+
+ /* ### Should we reorder the errors in this specific case
+ ### to avoid returning the normal error as top level error? */
+
+ err2 = svn_error_compose_create(err2,
+ svn_error_create(SVN_ERR_SQLITE_RESETTING_FOR_ROLLBACK,
+ NULL, NULL));
+
+ for (i = 0; i < db->nbr_statements; i++)
+ if (db->prepared_stmts[i] && db->prepared_stmts[i]->needs_reset)
+ err2 = svn_error_compose_create(
+ err2,
+ svn_sqlite__reset(db->prepared_stmts[i]));
+
+ err2 = svn_error_compose_create(
+ exec_sql(db, "ROLLBACK TRANSACTION;"),
+ err2);
+ }
+
+ return svn_error_compose_create(err,
+ err2);
}
return svn_error_return(exec_sql(db, "COMMIT TRANSACTION;"));
Modified: subversion/branches/performance/subversion/libsvn_subr/stream.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/stream.c?rev=993127&r1=993126&r2=993127&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/stream.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/stream.c Mon Sep 6 19:13:39 2010
@@ -51,7 +51,6 @@ struct svn_stream_t {
svn_write_fn_t write_fn;
svn_skip_fn_t skip_fn;
svn_close_fn_t close_fn;
- svn_io_reset_fn_t reset_fn;
svn_io_mark_fn_t mark_fn;
svn_io_seek_fn_t seek_fn;
svn_io_buffered_fn_t buffered_fn;
@@ -71,7 +70,6 @@ svn_stream_create(void *baton, apr_pool_
stream->skip_fn = NULL;
stream->write_fn = NULL;
stream->close_fn = NULL;
- stream->reset_fn = NULL;
stream->mark_fn = NULL;
stream->seek_fn = NULL;
stream->buffered_fn = NULL;
@@ -111,12 +109,6 @@ svn_stream_set_close(svn_stream_t *strea
}
void
-svn_stream_set_reset(svn_stream_t *stream, svn_io_reset_fn_t reset_fn)
-{
- stream->reset_fn = reset_fn;
-}
-
-void
svn_stream_set_mark(svn_stream_t *stream, svn_io_mark_fn_t mark_fn)
{
stream->mark_fn = mark_fn;
@@ -162,10 +154,8 @@ svn_stream_write(svn_stream_t *stream, c
svn_error_t *
svn_stream_reset(svn_stream_t *stream)
{
- if (stream->reset_fn == NULL)
- return svn_error_create(SVN_ERR_STREAM_RESET_NOT_SUPPORTED, NULL, NULL);
-
- return stream->reset_fn(stream->baton);
+ return svn_error_return(
+ svn_stream_seek(stream, NULL));
}
svn_boolean_t
@@ -669,14 +659,9 @@ write_handler_empty(void *baton, const c
}
static svn_error_t *
-reset_handler_empty(void *baton)
-{
- return SVN_NO_ERROR;
-}
-
-static svn_error_t *
mark_handler_empty(void *baton, svn_stream_mark_t **mark, apr_pool_t *pool)
{
+ *mark = NULL; /* Seek to start of stream marker */
return SVN_NO_ERROR;
}
@@ -702,7 +687,6 @@ svn_stream_empty(apr_pool_t *pool)
svn_stream_set_read(stream, read_handler_empty);
svn_stream_set_skip(stream, skip_handler_empty);
svn_stream_set_write(stream, write_handler_empty);
- svn_stream_set_reset(stream, reset_handler_empty);
svn_stream_set_mark(stream, mark_handler_empty);
svn_stream_set_seek(stream, seek_handler_empty);
svn_stream_set_buffered(stream, buffered_handler_empty);
@@ -789,12 +773,6 @@ write_handler_disown(void *baton, const
}
static svn_error_t *
-reset_handler_disown(void *baton)
-{
- return svn_stream_reset(baton);
-}
-
-static svn_error_t *
mark_handler_disown(void *baton, svn_stream_mark_t **mark, apr_pool_t *pool)
{
return svn_stream_mark(baton, mark, pool);
@@ -820,7 +798,6 @@ svn_stream_disown(svn_stream_t *stream,
svn_stream_set_read(s, read_handler_disown);
svn_stream_set_skip(s, skip_handler_disown);
svn_stream_set_write(s, write_handler_disown);
- svn_stream_set_reset(s, reset_handler_disown);
svn_stream_set_mark(s, mark_handler_disown);
svn_stream_set_seek(s, seek_handler_disown);
svn_stream_set_buffered(s, buffered_handler_disown);
@@ -926,19 +903,6 @@ close_handler_cached_handle(void *baton)
}
static svn_error_t *
-reset_handler_apr(void *baton)
-{
- apr_off_t offset;
- struct baton_apr *btn = baton;
-
- /* If we're reading from a range, reset to the start of the range.
- * Otherwise, reset to the start of the file. */
- offset = btn->start >= 0 ? btn->start : 0;
-
- return svn_io_file_seek(btn->file, APR_SET, &offset, btn->pool);
-}
-
-static svn_error_t *
mark_handler_apr(void *baton, svn_stream_mark_t **mark, apr_pool_t *pool)
{
struct baton_apr *btn = baton;
@@ -955,10 +919,25 @@ static svn_error_t *
seek_handler_apr(void *baton, svn_stream_mark_t *mark)
{
struct baton_apr *btn = baton;
- struct mark_apr *mark_apr;
- mark_apr = (struct mark_apr *)mark;
- SVN_ERR(svn_io_file_seek(btn->file, APR_SET, &mark_apr->off, btn->pool));
+ if (mark != NULL)
+ {
+ struct mark_apr *mark_apr;
+
+ mark_apr = (struct mark_apr *)mark;
+ SVN_ERR(svn_io_file_seek(btn->file, APR_SET, &mark_apr->off, btn->pool));
+ }
+ else
+ {
+ apr_off_t offset;
+
+ /* If we're reading from a range, reset to the start of the range.
+ * Otherwise, reset to the start of the file. */
+ offset = btn->start >= 0 ? btn->start : 0;
+
+ SVN_ERR(svn_io_file_seek(btn->file, APR_SET, &offset, btn->pool));
+ }
+
return SVN_NO_ERROR;
}
@@ -1047,7 +1026,6 @@ stream_from_aprfile(struct baton_apr **b
svn_stream_set_read(stream, read_handler_apr);
svn_stream_set_skip(stream, skip_handler_apr);
svn_stream_set_write(stream, write_handler_apr);
- svn_stream_set_reset(stream, reset_handler_apr);
svn_stream_set_mark(stream, mark_handler_apr);
svn_stream_set_seek(stream, seek_handler_apr);
svn_stream_set_buffered(stream, buffered_handler_apr);
@@ -1072,6 +1050,16 @@ svn_stream_from_aprfile2(apr_file_t *fil
/* construct and init the default stream structures */
stream = stream_from_aprfile(&baton, file, pool);
+ baton = apr_palloc(pool, sizeof(*baton));
+ baton->file = file;
+ baton->pool = pool;
+ baton->start = -1;
+ baton->end = -1;
+ stream = svn_stream_create(baton, pool);
+ svn_stream_set_read(stream, read_handler_apr);
+ svn_stream_set_write(stream, write_handler_apr);
+ svn_stream_set_mark(stream, mark_handler_apr);
+ svn_stream_set_seek(stream, seek_handler_apr);
/* make sure to close the file handle after use if we own it */
if (! disown)
@@ -1215,7 +1203,6 @@ svn_stream_from_aprfile_range_readonly(a
stream = svn_stream_create(baton, pool);
svn_stream_set_read(stream, read_range_handler_apr);
svn_stream_set_skip(stream, skip_range_handler_apr);
- svn_stream_set_reset(stream, reset_handler_apr);
svn_stream_set_mark(stream, mark_handler_apr);
svn_stream_set_seek(stream, seek_handler_apr);
svn_stream_set_buffered(stream, buffered_handler_apr);
@@ -1780,20 +1767,13 @@ write_handler_stringbuf(void *baton, con
}
static svn_error_t *
-reset_handler_stringbuf(void *baton)
-{
- struct stringbuf_stream_baton *btn = baton;
- btn->amt_read = 0;
- return SVN_NO_ERROR;
-}
-
-static svn_error_t *
mark_handler_stringbuf(void *baton, svn_stream_mark_t **mark, apr_pool_t *pool)
{
struct stringbuf_stream_baton *btn;
struct stringbuf_stream_mark *stringbuf_stream_mark;
btn = baton;
+
stringbuf_stream_mark = apr_palloc(pool, sizeof(*stringbuf_stream_mark));
stringbuf_stream_mark->pos = btn->amt_read;
*mark = (svn_stream_mark_t *)stringbuf_stream_mark;
@@ -1803,12 +1783,18 @@ mark_handler_stringbuf(void *baton, svn_
static svn_error_t *
seek_handler_stringbuf(void *baton, svn_stream_mark_t *mark)
{
- struct stringbuf_stream_baton *btn;
- struct stringbuf_stream_mark *stringbuf_stream_mark;
+ struct stringbuf_stream_baton *btn = baton;
+
+ if (mark != NULL)
+ {
+ struct stringbuf_stream_mark *stringbuf_stream_mark;
+
+ stringbuf_stream_mark = (struct stringbuf_stream_mark *)mark;
+ btn->amt_read = stringbuf_stream_mark->pos;
+ }
+ else
+ btn->amt_read = 0;
- btn = baton;
- stringbuf_stream_mark = (struct stringbuf_stream_mark *)mark;
- btn->amt_read = stringbuf_stream_mark->pos;
return SVN_NO_ERROR;
}
@@ -1835,7 +1821,6 @@ svn_stream_from_stringbuf(svn_stringbuf_
svn_stream_set_read(stream, read_handler_stringbuf);
svn_stream_set_skip(stream, skip_handler_stringbuf);
svn_stream_set_write(stream, write_handler_stringbuf);
- svn_stream_set_reset(stream, reset_handler_stringbuf);
svn_stream_set_mark(stream, mark_handler_stringbuf);
svn_stream_set_seek(stream, seek_handler_stringbuf);
svn_stream_set_buffered(stream, buffered_handler_stringbuf);
@@ -1848,6 +1833,11 @@ struct string_stream_baton
apr_size_t amt_read;
};
+/* svn_stream_mark_t for streams backed by stringbufs. */
+struct string_stream_mark {
+ apr_size_t pos;
+};
+
static svn_error_t *
read_handler_string(void *baton, char *buffer, apr_size_t *len)
{
@@ -1871,6 +1861,38 @@ skip_handler_string(void *baton, apr_siz
return SVN_NO_ERROR;
}
+static svn_error_t *
+mark_handler_string(void *baton, svn_stream_mark_t **mark, apr_pool_t *pool)
+{
+ struct string_stream_baton *btn;
+ struct string_stream_mark *marker;
+
+ btn = baton;
+
+ marker = apr_palloc(pool, sizeof(*marker));
+ marker->pos = btn->amt_read;
+ *mark = (svn_stream_mark_t *)marker;
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+seek_handler_string(void *baton, svn_stream_mark_t *mark)
+{
+ struct string_stream_baton *btn = baton;
+
+ if (mark != NULL)
+ {
+ struct string_stream_mark *marker;
+
+ marker = (struct string_stream_mark *)mark;
+ btn->amt_read = marker->pos;
+ }
+ else
+ btn->amt_read = 0;
+
+ return SVN_NO_ERROR;
+}
+
svn_stream_t *
svn_stream_from_string(const svn_string_t *str,
apr_pool_t *pool)
@@ -1887,6 +1909,8 @@ svn_stream_from_string(const svn_string_
stream = svn_stream_create(baton, pool);
svn_stream_set_read(stream, read_handler_string);
svn_stream_set_skip(stream, skip_handler_string);
+ svn_stream_set_mark(stream, mark_handler_string);
+ svn_stream_set_seek(stream, seek_handler_string);
return stream;
}
Modified: subversion/branches/performance/subversion/libsvn_subr/subst.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/subst.c?rev=993127&r1=993126&r2=993127&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/subst.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/subst.c Mon Sep 6 19:13:39 2010
@@ -1241,30 +1241,6 @@ translated_stream_close(void *baton)
return SVN_NO_ERROR;
}
-/* Implements svn_io_reset_fn_t. */
-static svn_error_t *
-translated_stream_reset(void *baton)
-{
- struct translated_stream_baton *b = baton;
- svn_error_t *err;
-
- err = svn_stream_reset(b->stream);
- if (err == NULL)
- {
- b->in_baton->newline_off = 0;
- b->in_baton->keyword_off = 0;
- b->in_baton->src_format_len = 0;
- b->out_baton->newline_off = 0;
- b->out_baton->keyword_off = 0;
- b->out_baton->src_format_len = 0;
-
- b->written = FALSE;
- svn_stringbuf_setempty(b->readbuf);
- b->readbuf_off = 0;
- }
-
- return svn_error_return(err);
-}
/* svn_stream_mark_t for translation streams. */
typedef struct
@@ -1306,23 +1282,43 @@ static svn_error_t *
translated_stream_seek(void *baton, svn_stream_mark_t *mark)
{
struct translated_stream_baton *b = baton;
- mark_translated_t *mt = (mark_translated_t *)mark;
- /* Flush output buffer if necessary. */
- if (b->written)
- SVN_ERR(translate_chunk(b->stream, b->out_baton, NULL, 0, b->iterpool));
-
- SVN_ERR(svn_stream_seek(b->stream, mt->mark));
-
- /* Restore translation state, avoiding new allocations. */
- *b->in_baton = *mt->saved_baton.in_baton;
- *b->out_baton = *mt->saved_baton.out_baton;
- b->written = mt->saved_baton.written;
- svn_stringbuf_setempty(b->readbuf);
- svn_stringbuf_appendbytes(b->readbuf, mt->saved_baton.readbuf->data,
- mt->saved_baton.readbuf->len);
- b->readbuf_off = mt->saved_baton.readbuf_off;
- memcpy(b->buf, mt->saved_baton.buf, SVN__TRANSLATION_BUF_SIZE);
+ if (mark != NULL)
+ {
+ mark_translated_t *mt = (mark_translated_t *)mark;
+
+ /* Flush output buffer if necessary. */
+ if (b->written)
+ SVN_ERR(translate_chunk(b->stream, b->out_baton, NULL, 0,
+ b->iterpool));
+
+ SVN_ERR(svn_stream_seek(b->stream, mt->mark));
+
+ /* Restore translation state, avoiding new allocations. */
+ *b->in_baton = *mt->saved_baton.in_baton;
+ *b->out_baton = *mt->saved_baton.out_baton;
+ b->written = mt->saved_baton.written;
+ svn_stringbuf_setempty(b->readbuf);
+ svn_stringbuf_appendbytes(b->readbuf, mt->saved_baton.readbuf->data,
+ mt->saved_baton.readbuf->len);
+ b->readbuf_off = mt->saved_baton.readbuf_off;
+ memcpy(b->buf, mt->saved_baton.buf, SVN__TRANSLATION_BUF_SIZE);
+ }
+ else
+ {
+ SVN_ERR(svn_stream_reset(b->stream));
+
+ b->in_baton->newline_off = 0;
+ b->in_baton->keyword_off = 0;
+ b->in_baton->src_format_len = 0;
+ b->out_baton->newline_off = 0;
+ b->out_baton->keyword_off = 0;
+ b->out_baton->src_format_len = 0;
+
+ b->written = FALSE;
+ svn_stringbuf_setempty(b->readbuf);
+ b->readbuf_off = 0;
+ }
return SVN_NO_ERROR;
}
@@ -1435,7 +1431,6 @@ svn_subst_stream_translated(svn_stream_t
svn_stream_set_skip(s, translated_stream_skip);
svn_stream_set_write(s, translated_stream_write);
svn_stream_set_close(s, translated_stream_close);
- svn_stream_set_reset(s, translated_stream_reset);
svn_stream_set_mark(s, translated_stream_mark);
svn_stream_set_seek(s, translated_stream_seek);
svn_stream_set_buffered(s, translated_stream_buffered);
Propchange: subversion/branches/performance/subversion/libsvn_subr/svn_file_handle_cache.c
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Sep 6 19:13:39 2010
@@ -0,0 +1 @@
+/subversion/trunk/subversion/libsvn_subr/svn_file_handle_cache.c:962911-970000
Propchange: subversion/branches/performance/subversion/libsvn_subr/svn_temp_serializer.c
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Sep 6 19:13:39 2010
@@ -0,0 +1 @@
+/subversion/trunk/subversion/libsvn_subr/svn_temp_serializer.c:962911-970000
Modified: subversion/branches/performance/subversion/libsvn_wc/adm_crawler.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/adm_crawler.c?rev=993127&r1=993126&r2=993127&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/adm_crawler.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/adm_crawler.c Mon Sep 6 19:13:39 2010
@@ -241,7 +241,8 @@ report_revisions_and_depths(svn_wc__db_t
dir_abspath = svn_dirent_join(anchor_abspath, dir_path, scratch_pool);
SVN_ERR(svn_wc__db_base_get_children(&base_children, db, dir_abspath,
scratch_pool, iterpool));
- SVN_ERR(svn_io_get_dir_filenames(&dirents, dir_abspath, scratch_pool));
+ SVN_ERR(svn_io_get_dirents3(&dirents, dir_abspath, TRUE,
+ scratch_pool, scratch_pool));
/*** Do the real reporting and recursing. ***/
@@ -1100,21 +1101,20 @@ svn_wc__internal_transmit_text_deltas(co
/* If the caller wants a copy of the working file translated to
* repository-normal form, make the copy by tee-ing the stream and set
- * *TEMPFILE to the path to it. */
+ * *TEMPFILE to the path to it. This is only needed for the 1.6 API,
+ * 1.7 doesn't set TEMPFILE. Even when using the 1.6 API this file
+ * is not used by the functions that would have used it when using
+ * the 1.6 code. It's possible that 3rd party users (if there are any)
+ * might expect this file to be a text-base. */
if (tempfile)
{
svn_stream_t *tempstream;
- SVN_ERR(svn_wc__text_base_deterministic_tmp_path(tempfile,
- db, local_abspath,
- result_pool));
-
- /* Make an untranslated copy of the working file in the
- administrative tmp area because a) we need to detranslate eol
- and keywords anyway, and b) after the commit, we're going to
- copy the tmp file to become the new text base anyway. */
- SVN_ERR(svn_stream_open_writable(&tempstream, *tempfile,
- scratch_pool, scratch_pool));
+ /* It can't be the same location as in 1.6 because the admin directory
+ no longer exists. */
+ SVN_ERR(svn_stream_open_unique(&tempstream, tempfile,
+ NULL, svn_io_file_del_none,
+ result_pool, scratch_pool));
/* Wrap the translated stream with a new stream that writes the
translated contents into the new text base file as we read from it.
@@ -1316,8 +1316,7 @@ svn_wc__internal_transmit_text_deltas(co
}
svn_error_t *
-svn_wc_transmit_text_deltas3(const char **tempfile,
- const svn_checksum_t **new_text_base_md5_checksum,
+svn_wc_transmit_text_deltas3(const svn_checksum_t **new_text_base_md5_checksum,
const svn_checksum_t **new_text_base_sha1_checksum,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
@@ -1327,7 +1326,7 @@ svn_wc_transmit_text_deltas3(const char
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- return svn_wc__internal_transmit_text_deltas(tempfile,
+ return svn_wc__internal_transmit_text_deltas(NULL,
new_text_base_md5_checksum,
new_text_base_sha1_checksum,
wc_ctx->db, local_abspath,
Modified: subversion/branches/performance/subversion/libsvn_wc/adm_files.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/adm_files.c?rev=993127&r1=993126&r2=993127&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/adm_files.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/adm_files.c Mon Sep 6 19:13:39 2010
@@ -189,24 +189,6 @@ make_adm_subdir(const char *path,
svn_error_t *
-svn_wc__text_base_deterministic_tmp_path(const char **result_abspath,
- svn_wc__db_t *db,
- const char *local_abspath,
- apr_pool_t *pool)
-{
- const char *newpath, *base_name;
-
- SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-
- svn_dirent_split(&newpath, &base_name, local_abspath, pool);
- *result_abspath = simple_extend(newpath, TRUE, SVN_WC__ADM_TEXT_BASE,
- base_name, SVN_WC__BASE_EXT, pool);
-
- return SVN_NO_ERROR;
-}
-
-
-svn_error_t *
svn_wc__text_base_path_to_read(const char **result_abspath,
svn_wc__db_t *db,
const char *local_abspath,
@@ -605,15 +587,15 @@ init_adm_tmp_area(const char *path, apr_
/* SVN_WC__ADM_TMP */
SVN_ERR(make_adm_subdir(path, SVN_WC__ADM_TMP, FALSE, pool));
- /* SVN_WC__ADM_TMP/SVN_WC__ADM_TEXT_BASE */
- SVN_ERR(make_adm_subdir(path, SVN_WC__ADM_TEXT_BASE, TRUE, pool));
-
+#if (SVN_WC__VERSION < 18)
/* SVN_WC__ADM_TMP/SVN_WC__ADM_PROP_BASE */
SVN_ERR(make_adm_subdir(path, SVN_WC__ADM_PROP_BASE, TRUE, pool));
/* SVN_WC__ADM_TMP/SVN_WC__ADM_PROPS */
- return svn_error_return(make_adm_subdir(path, SVN_WC__ADM_PROPS, TRUE,
- pool));
+ SVN_ERR(make_adm_subdir(path, SVN_WC__ADM_PROPS, TRUE, pool));
+#endif
+
+ return SVN_NO_ERROR;
}
@@ -637,11 +619,13 @@ init_adm(svn_wc__db_t *db,
/** Make subdirectories. ***/
+#if (SVN_WC__VERSION < 18)
/* SVN_WC__ADM_PROP_BASE */
SVN_ERR(make_adm_subdir(local_abspath, SVN_WC__ADM_PROP_BASE, FALSE, pool));
/* SVN_WC__ADM_PROPS */
SVN_ERR(make_adm_subdir(local_abspath, SVN_WC__ADM_PROPS, FALSE, pool));
+#endif
/* SVN_WC__ADM_PRISTINE */
SVN_ERR(make_adm_subdir(local_abspath, SVN_WC__ADM_PRISTINE, FALSE, pool));
@@ -757,7 +741,9 @@ svn_wc__adm_destroy(svn_wc__db_t *db,
const char *dir_abspath,
apr_pool_t *scratch_pool)
{
+#ifndef SINGLE_DB
const char *adm_abspath;
+#endif
SVN_ERR_ASSERT(svn_dirent_is_absolute(dir_abspath));
@@ -767,8 +753,10 @@ svn_wc__adm_destroy(svn_wc__db_t *db,
directory, which also removes the lock */
SVN_ERR(svn_wc__db_temp_forget_directory(db, dir_abspath, scratch_pool));
+#ifndef SINGLE_DB
adm_abspath = svn_wc__adm_child(dir_abspath, NULL, scratch_pool);
SVN_ERR(svn_io_remove_dir2(adm_abspath, FALSE, NULL, NULL, scratch_pool));
+#endif
return SVN_NO_ERROR;
}
Modified: subversion/branches/performance/subversion/libsvn_wc/adm_files.h
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/adm_files.h?rev=993127&r1=993126&r2=993127&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/adm_files.h (original)
+++ subversion/branches/performance/subversion/libsvn_wc/adm_files.h Mon Sep 6 19:13:39 2010
@@ -52,14 +52,6 @@ svn_boolean_t svn_wc__adm_area_exists(co
apr_pool_t *pool);
-/* Set *RESULT_ABSPATH to the deterministic absolute path to where
- LOCAL_ABSPATH's temporary text-base file is or should be created. */
-svn_error_t *
-svn_wc__text_base_deterministic_tmp_path(const char **result_abspath,
- svn_wc__db_t *db,
- const char *local_abspath,
- apr_pool_t *pool);
-
/* Set *CONTENTS to a readonly stream on the pristine text of the working
* version of the file LOCAL_ABSPATH in DB. If the file is locally copied
* or moved to this path, this means the pristine text of the copy source,
Modified: subversion/branches/performance/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/adm_ops.c?rev=993127&r1=993126&r2=993127&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/adm_ops.c Mon Sep 6 19:13:39 2010
@@ -546,75 +546,6 @@ svn_wc_process_committed_queue2(svn_wc_c
}
-/* Recursively mark a tree DIR_ABSPATH with schedule svn_wc_schedule_delete
- and a KEEP_LOCAL flag. */
-static svn_error_t *
-mark_tree_deleted(svn_wc__db_t *db,
- const char *dir_abspath,
- svn_boolean_t keep_local,
- svn_wc_notify_func2_t notify_func,
- void *notify_baton,
- apr_pool_t *pool)
-{
- apr_pool_t *iterpool = svn_pool_create(pool);
- const apr_array_header_t *children;
- int i;
-
- /* Read the entries file for this directory. */
- SVN_ERR(svn_wc__db_read_children(&children, db, dir_abspath,
- pool, iterpool));
-
- /* Mark each entry in the entries file. */
- for (i = 0; i < children->nelts; i++)
- {
- const char *child_basename = APR_ARRAY_IDX(children, i, const char *);
- const char *child_abspath;
- svn_boolean_t hidden;
- svn_wc__db_kind_t kind;
-
- /* Clear our per-iteration pool. */
- svn_pool_clear(iterpool);
-
- child_abspath = svn_dirent_join(dir_abspath, child_basename, iterpool);
-
- /* We exclude hidden nodes from this operation. */
- SVN_ERR(svn_wc__db_node_hidden(&hidden, db, child_abspath, iterpool));
- if (hidden)
- continue;
-
- SVN_ERR(svn_wc__db_read_kind(&kind, db, child_abspath, FALSE, iterpool));
-
- /* If this is a directory, recurse; otherwise, delete. */
- if (kind == svn_wc__db_kind_dir)
- {
- SVN_ERR(mark_tree_deleted(db, child_abspath,
- keep_local,
- notify_func, notify_baton,
- iterpool));
- }
- else
- {
- SVN_ERR(svn_wc__db_temp_op_delete(db, child_abspath, iterpool));
- }
-
- /* Tell someone what we've done. */
- if (notify_func != NULL)
- notify_func(notify_baton,
- svn_wc_create_notify(child_abspath,
- svn_wc_notify_delete,
- iterpool),
- iterpool);
- }
-
- /* Handle directories now, after handling their kiddos. */
- SVN_ERR(svn_wc__db_temp_op_delete(db, dir_abspath, iterpool));
- if (keep_local)
- SVN_ERR(svn_wc__db_temp_set_keep_local(db, dir_abspath, TRUE, iterpool));
-
- /* Destroy our per-iteration pool. */
- svn_pool_destroy(iterpool);
- return SVN_NO_ERROR;
-}
/* Remove/erase PATH from the working copy. This involves deleting PATH
* from the physical filesystem. PATH is assumed to be an unversioned file
@@ -755,7 +686,8 @@ erase_from_wc(svn_wc__db_t *db,
}
/* Now handle any remaining unversioned items */
- err = svn_io_get_dirents2(&unversioned, local_abspath, scratch_pool);
+ err = svn_io_get_dirents3(&unversioned, local_abspath, TRUE,
+ scratch_pool, scratch_pool);
if (err)
{
svn_pool_destroy(iterpool);
@@ -813,7 +745,6 @@ svn_wc_delete4(svn_wc_context_t *wc_ctx,
svn_wc__db_t *db = wc_ctx->db;
svn_boolean_t was_add = FALSE, was_replace = FALSE;
svn_boolean_t was_copied = FALSE;
- svn_boolean_t was_deleted = FALSE; /* Silence a gcc uninitialized warning */
svn_error_t *err;
svn_wc__db_status_t status;
svn_wc__db_kind_t kind;
@@ -880,56 +811,42 @@ svn_wc_delete4(svn_wc_context_t *wc_ctx,
}
}
- /* ### Maybe we should disallow deleting switched nodes here? */
-
if (kind == svn_wc__db_kind_dir)
{
- svn_revnum_t unused_base_rev;
-
- SVN_ERR(svn_wc__db_temp_is_dir_deleted(&was_deleted, &unused_base_rev,
- db, local_abspath, pool));
+
+ apr_pool_t *iterpool = svn_pool_create(pool);
+ const apr_array_header_t *children;
+ int i;
- if (was_add && !was_deleted)
+ SVN_ERR(svn_wc__db_read_children(&children, db, local_abspath,
+ pool, pool));
+
+ for (i = 0; i < children->nelts; i++)
{
- /* Deleting a directory that has been added but not yet
- committed is easy, just remove the administrative dir. */
+ const char *child_basename = APR_ARRAY_IDX(children, i, const char *);
+ const char *child_abspath;
+ svn_boolean_t hidden;
- SVN_ERR(svn_wc__internal_remove_from_revision_control(
- wc_ctx->db,
- local_abspath,
- FALSE, FALSE,
- cancel_func, cancel_baton,
- pool));
- }
- else if (!was_add)
- {
- svn_boolean_t available;
+ svn_pool_clear(iterpool);
- /* If the working copy in the subdirectory is not available,
- we can't mark its tree as deleted. */
- SVN_ERR(svn_wc__adm_available(&available, NULL, NULL,
- wc_ctx->db, local_abspath,
- pool));
+ child_abspath = svn_dirent_join(local_abspath, child_basename,
+ iterpool);
+ SVN_ERR(svn_wc__db_node_hidden(&hidden, db, child_abspath, iterpool));
+ if (hidden)
+ continue;
- if (available)
- {
- /* Recursively mark a whole tree for deletion. */
- SVN_ERR(mark_tree_deleted(wc_ctx->db,
- local_abspath,
- keep_local,
- notify_func, notify_baton,
- pool));
- }
+ SVN_ERR(svn_wc_delete4(wc_ctx, child_abspath,
+ keep_local, delete_unversioned_target,
+ cancel_func, cancel_baton,
+ notify_func, notify_baton,
+ iterpool));
}
- /* else
- ### Handle added directory that is deleted in parent_access
- (was_deleted=TRUE). The current behavior is to just delete the
- directory with its administrative area inside, which is OK for
- WC-1.0, but when we move to a single database per working copy
- something must unversion the directory. */
+
+ svn_pool_destroy(iterpool);
}
- if (kind != svn_wc__db_kind_dir || !was_add || was_deleted)
+ /* ### Maybe we should disallow deleting switched nodes here? */
+
{
const char *parent_abspath = svn_dirent_dirname(local_abspath, pool);
@@ -939,6 +856,8 @@ svn_wc_delete4(svn_wc_context_t *wc_ctx,
Luckily most of this is for free once properties and pristine
are handled in the WC-NG way. */
SVN_ERR(svn_wc__db_temp_op_delete(wc_ctx->db, local_abspath, pool));
+ if (keep_local)
+ SVN_ERR(svn_wc__db_temp_set_keep_local(db, local_abspath, TRUE, pool));
SVN_ERR(svn_wc__wq_add_delete(wc_ctx->db, parent_abspath, local_abspath,
kind, was_add, was_copied, was_replace,
pool));
@@ -1106,6 +1025,8 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
svn_dirent_local_style(local_abspath, scratch_pool));
#endif
+ SVN_ERR(svn_wc__write_check(db, parent_abspath, scratch_pool));
+
{
svn_wc__db_status_t parent_status;
svn_wc__db_kind_t parent_kind;
@@ -1268,12 +1189,14 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
}
#endif
+#ifndef SVN_WC__SINGLE_DB
if (kind == svn_node_dir && !exists)
{
/* Lock on parent needs to be propogated into the child db. */
- SVN_ERR(svn_wc__db_wclock_set(db, local_abspath, 0, scratch_pool));
- SVN_ERR(svn_wc__db_temp_mark_locked(db, local_abspath, scratch_pool));
+ SVN_ERR(svn_wc__db_wclock_obtain(db, local_abspath, 0, FALSE,
+ scratch_pool));
}
+#endif
#if (SVN_WC__VERSION < SVN_WC__PROPS_IN_DB)
/* ### this is totally bogus. we clear these cuz turds might have been
@@ -1322,8 +1245,26 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
}
}
else if (!copyfrom_url)
- SVN_ERR(svn_wc__db_op_add_directory(db, local_abspath, NULL,
- scratch_pool));
+ {
+ SVN_ERR(svn_wc__db_op_add_directory(db, local_abspath, NULL,
+ scratch_pool));
+#ifdef SVN_WC__SINGLE_DB
+ if (!exists)
+ {
+ /* If using the legacy 1.6 interface the parent lock may not
+ be recursive and add is expected to lock the new dir.
+
+ ### Perhaps the lock should be created in the same
+ transaction that adds the node? */
+ svn_boolean_t locked;
+ SVN_ERR(svn_wc_locked2(&locked, NULL, wc_ctx, local_abspath,
+ scratch_pool));
+ if (!locked)
+ SVN_ERR(svn_wc__db_wclock_obtain(db, local_abspath, 0, FALSE,
+ scratch_pool));
+ }
+#endif
+ }
else if (!is_wc_root)
SVN_ERR(svn_wc__db_op_copy_dir(db,
local_abspath,
@@ -1350,6 +1291,7 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
const char *absent_repos_relpath, *absent_repos_root_url;
const char *absent_repos_uuid;
svn_revnum_t absent_revision;
+ svn_boolean_t owns_lock;
/* Read the not present status from the parent working copy,
to reinsert it after hooking up the child working copy */
@@ -1393,6 +1335,15 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
scratch_pool));
else
SVN_ERR(svn_wc__db_base_remove(db, local_abspath, scratch_pool));
+
+ /* The subdir is now part of our parent working copy. Our caller assumes
+ that we return the new node locked, so obtain a lock if we didn't
+ receive the lock via our depth infinity lock */
+ SVN_ERR(svn_wc__db_wclock_owns_lock(&owns_lock, db, local_abspath, FALSE,
+ scratch_pool));
+ if (!owns_lock)
+ SVN_ERR(svn_wc__db_wclock_obtain(db, local_abspath, 0, FALSE,
+ scratch_pool));
}
/* Report the addition to the caller. */
@@ -2018,8 +1969,9 @@ svn_wc__internal_remove_from_revision_co
/* Only check if the file was modified when it wasn't overwritten with a
special file */
- SVN_ERR(svn_wc__get_special(&wc_special, db, local_abspath,
- scratch_pool));
+ SVN_ERR(svn_wc__get_translate_info(NULL, NULL, NULL,
+ &wc_special, db, local_abspath,
+ scratch_pool, scratch_pool));
SVN_ERR(svn_io_check_special_path(local_abspath, &on_disk,
&local_special, scratch_pool));
if (wc_special || ! local_special)
@@ -2409,7 +2361,12 @@ svn_wc__set_file_external_location(svn_w
if (url)
{
external_repos_relpath = svn_uri_is_child(repos_root_url, url, NULL);
- SVN_ERR_ASSERT(external_repos_relpath != NULL);
+
+ if (external_repos_relpath == NULL)
+ return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+ _("Can't add a file external to '%s' as it"
+ " is not a file in repository '%s'."),
+ url, repos_root_url);
external_repos_relpath = svn_path_uri_decode(external_repos_relpath,
scratch_pool);
Modified: subversion/branches/performance/subversion/libsvn_wc/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/copy.c?rev=993127&r1=993126&r2=993127&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/copy.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/copy.c Mon Sep 6 19:13:39 2010
@@ -259,9 +259,9 @@ copy_versioned_file(svn_wc__db_t *db,
{
svn_skel_t *work_item;
- SVN_ERR(svn_wc__loggy_move(&work_item, db, dir_abspath,
- tmp_dst_abspath, dst_abspath,
- scratch_pool));
+ SVN_ERR(svn_wc__wq_build_file_move(&work_item, db,
+ tmp_dst_abspath, dst_abspath,
+ scratch_pool, scratch_pool));
work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
}
@@ -312,11 +312,12 @@ copy_versioned_dir(svn_wc__db_t *db,
{
svn_skel_t *work_item;
- SVN_ERR(svn_wc__loggy_move(&work_item, db, dir_abspath,
- tmp_dst_abspath, dst_abspath,
- scratch_pool));
+ SVN_ERR(svn_wc__wq_build_file_move(&work_item, db,
+ tmp_dst_abspath, dst_abspath,
+ scratch_pool, scratch_pool));
work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
+#ifndef SVN_WC__SINGLE_DB
if (kind == svn_node_dir)
{
/* Create the per-directory db in the copied directory. The
@@ -362,7 +363,35 @@ copy_versioned_dir(svn_wc__db_t *db,
if (!repos_root_url)
{
- if (status == svn_wc__db_status_added || !have_base)
+ if (status == svn_wc__db_status_deleted)
+ {
+ const char *work_del_abspath;
+
+ SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL, NULL,
+ &work_del_abspath,
+ db, src_abspath,
+ scratch_pool, scratch_pool));
+ if (work_del_abspath)
+ {
+ const char *parent_del_abspath
+ = svn_dirent_dirname(work_del_abspath, scratch_pool);
+
+ SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL,
+ &repos_root_url,
+ &repos_uuid,
+ NULL, NULL, NULL, NULL,
+ db, parent_del_abspath,
+ scratch_pool,
+ scratch_pool));
+ }
+ else
+ SVN_ERR(svn_wc__db_scan_base_repos(NULL, &repos_root_url,
+ &repos_uuid,
+ db, src_abspath,
+ scratch_pool,
+ scratch_pool));
+ }
+ else if (status == svn_wc__db_status_added || !have_base)
SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL,
&repos_root_url, &repos_uuid,
NULL, NULL, NULL, NULL,
@@ -391,6 +420,7 @@ copy_versioned_dir(svn_wc__db_t *db,
SVN_ERR(svn_wc__db_temp_forget_directory(db, tmp_dst_abspath,
scratch_pool));
}
+#endif
}
#if (SVN_WC__VERSION < SVN_WC__PROPS_IN_DB)
@@ -454,8 +484,11 @@ copy_versioned_dir(svn_wc__db_t *db,
}
if (kind == svn_node_dir)
- /* All children, versioned and unversioned */
- SVN_ERR(svn_io_get_dirents2(&children, src_abspath, scratch_pool));
+ /* All children, versioned and unversioned. We're only interested in the
+ names of the children, so we can pass TRUE as the only_check_type
+ param. */
+ SVN_ERR(svn_io_get_dirents3(&children, src_abspath, TRUE,
+ scratch_pool, scratch_pool));
/* Copy all the versioned children */
SVN_ERR(svn_wc__db_read_children(&versioned_children, db, src_abspath,
@@ -526,9 +559,10 @@ copy_versioned_dir(svn_wc__db_t *db,
if (tmp_dst_abspath)
{
svn_skel_t *work_item;
- SVN_ERR(svn_wc__loggy_move(&work_item, db, dir_abspath,
- tmp_dst_abspath, unver_dst_abspath,
- iterpool));
+ SVN_ERR(svn_wc__wq_build_file_move(&work_item, db,
+ tmp_dst_abspath,
+ unver_dst_abspath,
+ iterpool, iterpool));
SVN_ERR(svn_wc__db_wq_add(db, dst_abspath, work_item,
iterpool));
}
Modified: subversion/branches/performance/subversion/libsvn_wc/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/deprecated.c?rev=993127&r1=993126&r2=993127&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/deprecated.c Mon Sep 6 19:13:39 2010
@@ -42,6 +42,7 @@
#include "entries.h"
#include "lock.h"
#include "props.h"
+#include "translate.h"
#include "workqueue.h"
#include "svn_private_config.h"
@@ -420,12 +421,14 @@ svn_wc_transmit_text_deltas2(const char
svn_wc__adm_get_db(adm_access),
pool));
- SVN_ERR(svn_wc_transmit_text_deltas3(tempfile,
- digest ? &new_text_base_md5_checksum
- : NULL,
- NULL, wc_ctx,
- local_abspath, fulltext, editor,
- file_baton, pool, pool));
+ SVN_ERR(svn_wc__internal_transmit_text_deltas(tempfile,
+ (digest
+ ? &new_text_base_md5_checksum
+ : NULL),
+ NULL, wc_ctx->db,
+ local_abspath, fulltext,
+ editor, file_baton,
+ pool, pool));
if (digest)
memcpy(digest, new_text_base_md5_checksum->digest, APR_MD5_DIGESTSIZE);
@@ -2216,12 +2219,18 @@ svn_wc_prop_get(const svn_string_t **val
svn_wc_context_t *wc_ctx;
const char *local_abspath;
+ svn_error_t *err;
SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */,
svn_wc__adm_get_db(adm_access), pool));
- SVN_ERR(svn_wc_prop_get2(value, wc_ctx, local_abspath, name, pool, pool));
+ err = svn_wc_prop_get2(value, wc_ctx, local_abspath, name, pool, pool);
+
+ if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+ svn_error_clear(err);
+ else
+ SVN_ERR(err);
return svn_error_return(svn_wc_context_destroy(wc_ctx));
}
@@ -3293,19 +3302,14 @@ svn_wc_translated_stream(svn_stream_t **
{
const char *local_abspath;
const char *versioned_abspath;
- svn_wc_context_t *wc_ctx;
SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
SVN_ERR(svn_dirent_get_absolute(&versioned_abspath, versioned_file, pool));
- SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL /* config */,
- svn_wc__adm_get_db(adm_access),
- pool));
- SVN_ERR(svn_wc_translated_stream2(stream, wc_ctx, local_abspath,
- versioned_abspath, flags,
- pool, pool));
-
- return svn_error_return(svn_wc_context_destroy(wc_ctx));
+ return svn_error_return(
+ svn_wc__internal_translated_stream(stream, svn_wc__adm_get_db(adm_access),
+ local_abspath, versioned_abspath, flags,
+ pool, pool));
}
svn_error_t *
@@ -3319,15 +3323,13 @@ svn_wc_translated_file2(const char **xla
const char *versioned_abspath;
const char *root;
const char *tmp_root;
- svn_wc_context_t *wc_ctx;
SVN_ERR(svn_dirent_get_absolute(&versioned_abspath, versioned_file, pool));
- SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL,
- svn_wc__adm_get_db(adm_access),
- pool));
- SVN_ERR(svn_wc_translated_file3(xlated_path, src, wc_ctx, versioned_abspath,
- flags, NULL, NULL, pool, pool));
+ SVN_ERR(svn_wc__internal_translated_file(xlated_path, src,
+ svn_wc__adm_get_db(adm_access),
+ versioned_abspath,
+ flags, NULL, NULL, pool, pool));
if (! svn_dirent_is_absolute(versioned_file))
{
SVN_ERR(svn_io_temp_dir(&tmp_root, pool));
@@ -3338,7 +3340,7 @@ svn_wc_translated_file2(const char **xla
}
}
- return svn_error_return(svn_wc_context_destroy(wc_ctx));
+ return SVN_NO_ERROR;
}
/*** From relocate.c ***/
Modified: subversion/branches/performance/subversion/libsvn_wc/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_wc/lock.c?rev=993127&r1=993126&r2=993127&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_wc/lock.c (original)
+++ subversion/branches/performance/subversion/libsvn_wc/lock.c Mon Sep 6 19:13:39 2010
@@ -204,7 +204,7 @@ pool_cleanup_locked(void *p)
{
/* There is no remaining work, so we're good to remove any
potential "physical" lock. */
- err = svn_wc__db_wclock_remove(db, lock->abspath, scratch_pool);
+ err = svn_wc__db_wclock_release(db, lock->abspath, scratch_pool);
}
}
svn_error_clear(err);
@@ -312,7 +312,8 @@ adm_access_alloc(svn_wc_adm_access_t **a
svn_boolean_t owns_lock;
/* If the db already owns a lock, we can't add an extra lock record */
- SVN_ERR(svn_wc__db_temp_own_lock(&owns_lock, db, path, scratch_pool));
+ SVN_ERR(svn_wc__db_wclock_owns_lock(&owns_lock, db, path, FALSE,
+ scratch_pool));
/* If DB owns the lock, but when there is no access baton open for this
directory, old access baton based code is trying to access data that
@@ -321,9 +322,8 @@ adm_access_alloc(svn_wc_adm_access_t **a
if (!owns_lock
|| svn_wc__adm_retrieve_internal2(db, lock->abspath, scratch_pool))
{
- SVN_ERR(svn_wc__db_wclock_set(db, lock->abspath, 0, scratch_pool));
-
- SVN_ERR(svn_wc__db_temp_mark_locked(db, lock->abspath, scratch_pool));
+ SVN_ERR(svn_wc__db_wclock_obtain(db, lock->abspath, 0, FALSE,
+ scratch_pool));
}
}
@@ -332,7 +332,7 @@ adm_access_alloc(svn_wc_adm_access_t **a
if (err)
return svn_error_compose_create(
err,
- svn_wc__db_wclock_remove(db, lock->abspath, scratch_pool));
+ svn_wc__db_wclock_release(db, lock->abspath, scratch_pool));
/* ### does this utf8 thing really/still apply?? */
/* It's important that the cleanup handler is registered *after* at least
@@ -516,8 +516,9 @@ close_single(svn_wc_adm_access_t *adm_ac
return SVN_NO_ERROR;
/* Physically unlock if required */
- SVN_ERR(svn_wc__db_temp_own_lock(&locked, adm_access->db,
- adm_access->abspath, scratch_pool));
+ SVN_ERR(svn_wc__db_wclock_owns_lock(&locked, adm_access->db,
+ adm_access->abspath, TRUE,
+ scratch_pool));
if (locked)
{
if (!preserve_lock)
@@ -528,9 +529,9 @@ close_single(svn_wc_adm_access_t *adm_ac
from the working copy. It is an error for the lock to
have disappeared if the administrative area still exists. */
- svn_error_t *err = svn_wc__db_wclock_remove(adm_access->db,
- adm_access->abspath,
- scratch_pool);
+ svn_error_t *err = svn_wc__db_wclock_release(adm_access->db,
+ adm_access->abspath,
+ scratch_pool);
if (err)
{
if (svn_wc__adm_area_exists(adm_access->abspath, scratch_pool))
@@ -1051,43 +1052,15 @@ child_is_disjoint(svn_boolean_t *disjoin
const char *node_repos_root, *node_repos_relpath, *node_repos_uuid;
const char *parent_repos_root, *parent_repos_relpath, *parent_repos_uuid;
svn_wc__db_status_t parent_status;
- const apr_array_header_t *children;
const char *parent_abspath, *base;
- svn_error_t *err;
- svn_boolean_t found_in_parent = FALSE;
- int i;
-
- svn_dirent_split(&parent_abspath, &base, local_abspath, scratch_pool);
/* Check if the parent directory knows about this node */
- err = svn_wc__db_read_children(&children, db, parent_abspath, scratch_pool,
- scratch_pool);
+ SVN_ERR(svn_wc__db_is_wcroot(disjoint, db, local_abspath, scratch_pool));
- if (err && err->apr_err == SVN_ERR_WC_NOT_DIRECTORY)
- {
- svn_error_clear(err);
- *disjoint = TRUE;
- return SVN_NO_ERROR;
- }
- else
- SVN_ERR(err);
-
- for (i = 0; i < children->nelts; i++)
- {
- const char *name = APR_ARRAY_IDX(children, i, const char *);
-
- if (strcmp(name, base) == 0)
- {
- found_in_parent = TRUE;
- break;
- }
- }
+ if (*disjoint)
+ return SVN_NO_ERROR;
- if (!found_in_parent)
- {
- *disjoint = TRUE;
- return SVN_NO_ERROR;
- }
+ svn_dirent_split(&parent_abspath, &base, local_abspath, scratch_pool);
SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL, &node_repos_relpath,
&node_repos_root, &node_repos_uuid, NULL, NULL,
@@ -1096,8 +1069,8 @@ child_is_disjoint(svn_boolean_t *disjoin
db, local_abspath,
scratch_pool, scratch_pool));
- /* If the node does not have its own relpath, its value is inherited
- which tells us that it is not disjoint. */
+ /* If the node does not have its own repos_relpath, its value is inherited
+ from a parent node, which implies that the node is not disjoint. */
if (node_repos_relpath == NULL)
{
*disjoint = FALSE;
@@ -1419,9 +1392,9 @@ svn_wc_adm_locked(const svn_wc_adm_acces
{
svn_boolean_t locked;
apr_pool_t *subpool = svn_pool_create(adm_access->pool);
- svn_error_t *err = svn_wc__db_temp_own_lock(&locked, adm_access->db,
- adm_access->abspath,
- subpool);
+ svn_error_t *err = svn_wc__db_wclock_owns_lock(&locked, adm_access->db,
+ adm_access->abspath, TRUE,
+ subpool);
svn_pool_destroy(subpool);
if (err)
@@ -1441,7 +1414,8 @@ svn_wc__write_check(svn_wc__db_t *db,
{
svn_boolean_t locked;
- SVN_ERR(svn_wc__db_temp_own_lock(&locked, db, local_abspath, scratch_pool));
+ SVN_ERR(svn_wc__db_wclock_owns_lock(&locked, db, local_abspath, FALSE,
+ scratch_pool));
if (!locked)
return svn_error_createf(SVN_ERR_WC_NOT_LOCKED, NULL,
_("No write-lock in '%s'"),
@@ -1461,8 +1435,8 @@ svn_wc_locked2(svn_boolean_t *locked_her
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
if (locked_here != NULL)
- SVN_ERR(svn_wc__db_temp_own_lock(locked_here, wc_ctx->db, local_abspath,
- scratch_pool));
+ SVN_ERR(svn_wc__db_wclock_owns_lock(locked_here, wc_ctx->db, local_abspath,
+ FALSE, scratch_pool));
if (locked != NULL)
SVN_ERR(svn_wc__db_wclocked(locked, wc_ctx->db, local_abspath,
scratch_pool));
@@ -1552,30 +1526,124 @@ svn_wc__adm_missing(svn_wc__db_t *db,
return (kind == svn_wc__db_kind_dir) && !available && obstructed;
}
+#ifndef SVN_WC__SINGLE_DB
+static svn_error_t *
+acquire_locks_recursively(svn_wc_context_t *wc_ctx,
+ const char* local_abspath,
+ svn_boolean_t lock_root,
+ apr_pool_t *scratch_pool)
+{
+ svn_wc__db_t *db = wc_ctx->db;
+ const apr_array_header_t *children;
+ apr_pool_t *iterpool;
+ svn_error_t *err;
+ int i;
+ int format;
+
+ iterpool = svn_pool_create(scratch_pool);
+
+ SVN_ERR(svn_wc__db_read_children(&children, wc_ctx->db, local_abspath,
+ scratch_pool, iterpool));
+
+ /* The current lock paradigm is that each directory holds a lock for itself,
+ and there are no inherited locks. In the eventual wc-ng paradigm, a
+ lock on a directory, would imply a infinite-depth lock on the children.
+ But since we aren't quite there yet, we do the infinite locking
+ manually (and be sure to release them in svn_wc__release_write_lock(). */
+
+ for (i = 0; i < children->nelts; i ++)
+ {
+ svn_wc__db_kind_t kind;
+ const char *child_relpath = APR_ARRAY_IDX(children, i, const char *);
+ const char *child_abspath;
+
+ svn_pool_clear(iterpool);
+ child_abspath = svn_dirent_join(local_abspath, child_relpath, iterpool);
+
+ SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, child_abspath, FALSE,
+ iterpool));
+ if (kind == svn_wc__db_kind_dir)
+ {
+ err = acquire_locks_recursively(wc_ctx, child_abspath, FALSE,
+ iterpool);
+ if (err && err->apr_err == SVN_ERR_WC_LOCKED)
+ {
+ while(i >= 0)
+ {
+ svn_error_t *err2;
+ svn_pool_clear(iterpool);
+ child_relpath = APR_ARRAY_IDX(children, i, const char *);
+ child_abspath = svn_dirent_join(local_abspath, child_relpath,
+ iterpool);
+
+ /* Don't release locks on non-directories as that will
+ try to release the lock on the parent directory! */
+ err2 = svn_wc__db_read_kind(&kind, wc_ctx->db, child_abspath,
+ FALSE, iterpool);
+
+ if (!err2 && kind == svn_wc__db_kind_dir)
+ err2 = svn_wc__release_write_lock(wc_ctx, child_abspath,
+ iterpool);
+
+ err = svn_error_compose_create(err, err2);
+ --i;
+ }
+ return svn_error_return(err);
+ }
+ }
+ }
+
+ if (lock_root)
+ SVN_ERR(svn_wc__db_wclock_obtain(db, local_abspath, 0, FALSE, iterpool));
+ else
+ {
+ /* We don't want to try and lock an unversioned directory that
+ obstructs a versioned directory. */
+ err = svn_wc__internal_check_wc(&format, wc_ctx->db, local_abspath,
+ iterpool);
+
+ if (!err && format)
+ SVN_ERR(svn_wc__db_wclock_obtain(wc_ctx->db, local_abspath, 0, FALSE,
+ iterpool));
+
+ svn_error_clear(err);
+ }
+ svn_pool_destroy(iterpool);
+
+ return SVN_NO_ERROR;
+}
+#endif
svn_error_t *
-svn_wc__acquire_write_lock(const char **anchor_abspath,
+svn_wc__acquire_write_lock(const char **lock_root_abspath,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
+ svn_boolean_t lock_anchor,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
+ svn_wc__db_t *db = wc_ctx->db;
svn_wc__db_kind_t kind;
- apr_pool_t *iterpool;
- const apr_array_header_t *children;
- int format, i;
svn_error_t *err;
-
- SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, local_abspath, TRUE,
+ SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, local_abspath,
+ (lock_root_abspath != NULL),
scratch_pool));
- if (anchor_abspath)
+ if (!lock_root_abspath && kind != svn_wc__db_kind_dir)
+ return svn_error_createf(SVN_ERR_WC_NOT_DIRECTORY, NULL,
+ _("Can't obtain lock on non-directory '%s'."),
+ svn_dirent_local_style(local_abspath,
+ scratch_pool));
+
+ if (lock_anchor)
{
const char *parent_abspath;
svn_wc__db_kind_t parent_kind;
+ SVN_ERR_ASSERT(lock_root_abspath != NULL);
+
parent_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
- err = svn_wc__db_read_kind(&parent_kind, wc_ctx->db, parent_abspath, TRUE,
+ err = svn_wc__db_read_kind(&parent_kind, db, parent_abspath, TRUE,
scratch_pool);
if (err && SVN_WC__ERR_IS_NOT_CURRENT_WC(err))
{
@@ -1600,67 +1668,36 @@ svn_wc__acquire_write_lock(const char **
_("'%s' is not a working copy"),
svn_dirent_local_style(local_abspath,
scratch_pool));
-
- *anchor_abspath = apr_pstrdup(result_pool, local_abspath);
}
else if (kind != svn_wc__db_kind_dir)
- local_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
-
- SVN_ERR(svn_wc__db_read_children(&children, wc_ctx->db, local_abspath,
- scratch_pool, scratch_pool));
-
- /* The current lock paradigm is that each directory holds a lock for itself,
- and there are no inherited locks. In the eventual wc-ng paradigm, a
- lock on a directory, would imply a infinite-depth lock on the children.
- But since we aren't quite there yet, we do the infinite locking
- manually (and be sure to release them in svn_wc__release_write_lock(). */
-
- iterpool = svn_pool_create(scratch_pool);
- for (i = 0; i < children->nelts; i ++)
{
- const char *child_relpath = APR_ARRAY_IDX(children, i, const char *);
- const char *child_abspath;
-
- svn_pool_clear(iterpool);
- child_abspath = svn_dirent_join(local_abspath, child_relpath, iterpool);
+ local_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
- SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, child_abspath, FALSE,
- iterpool));
- if (kind == svn_wc__db_kind_dir)
+ /* Can't lock parents that don't exist */
+ if (kind == svn_wc__db_kind_unknown)
{
- err = svn_wc__acquire_write_lock(NULL, wc_ctx, child_abspath, NULL,
- iterpool);
- if (err && err->apr_err == SVN_ERR_WC_LOCKED)
- {
- while(i >= 0)
- {
- svn_error_t *err2;
- svn_pool_clear(iterpool);
- child_relpath = APR_ARRAY_IDX(children, i, const char *);
- child_abspath = svn_dirent_join(local_abspath, child_relpath,
- iterpool);
- err2 = svn_wc__release_write_lock(wc_ctx, child_abspath,
- iterpool);
- if (err2)
- svn_error_compose(err, err2);
- --i;
- }
- return svn_error_return(err);
- }
+ SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath, FALSE,
+ scratch_pool));
+
+ if (kind != svn_wc__db_kind_dir)
+ return svn_error_createf(
+ SVN_ERR_WC_NOT_DIRECTORY, NULL,
+ _("Can't obtain lock on non-directory '%s'."),
+ svn_dirent_local_style(local_abspath,
+ scratch_pool));
}
}
- /* We don't want to try and lock an unversioned directory that
- obstructs a versioned directory. */
- err = svn_wc__internal_check_wc(&format, wc_ctx->db, local_abspath, iterpool);
- if (!err && format)
- {
- SVN_ERR(svn_wc__db_wclock_set(wc_ctx->db, local_abspath, 0, iterpool));
- SVN_ERR(svn_wc__db_temp_mark_locked(wc_ctx->db, local_abspath, iterpool));
- }
- svn_error_clear(err);
+ if (lock_root_abspath)
+ *lock_root_abspath = apr_pstrdup(result_pool, local_abspath);
- svn_pool_destroy(iterpool);
+#ifndef SVN_WC__SINGLE_DB
+ SVN_ERR(acquire_locks_recursively(wc_ctx, local_abspath, TRUE,
+ scratch_pool));
+#else
+ SVN_ERR(svn_wc__db_wclock_obtain(wc_ctx->db, local_abspath, -1, FALSE,
+ scratch_pool));
+#endif
return SVN_NO_ERROR;
}
@@ -1679,10 +1716,20 @@ svn_wc__release_write_lock(svn_wc_contex
svn_boolean_t locked_here;
int i;
- SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, local_abspath, TRUE,
- scratch_pool));
- if (kind != svn_wc__db_kind_dir)
- local_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
+#ifndef SVN_WC__SINGLE_DB
+ SVN_ERR(svn_wc__db_wclock_owns_lock(&locked_here, wc_ctx->db, local_abspath,
+ TRUE, scratch_pool));
+
+ if (!locked_here)
+ {
+ /* Make wclock_release() check if the node should have been locked,
+ like when the node is no wcroot (so can't have a multi-db lock) */
+ SVN_ERR(svn_wc__db_wclock_release(wc_ctx->db, local_abspath,
+ scratch_pool));
+
+ return SVN_NO_ERROR;
+ }
+#endif
SVN_ERR(svn_wc__db_wq_fetch(&id, &work_item, wc_ctx->db, local_abspath,
scratch_pool, scratch_pool));
@@ -1692,6 +1739,7 @@ svn_wc__release_write_lock(svn_wc_contex
return SVN_NO_ERROR;
}
+#ifndef SVN_WC__SINGLE_DB
/* We need to recursively remove locks (see comment in
svn_wc__acquire_write_lock(). */
@@ -1710,16 +1758,24 @@ svn_wc__release_write_lock(svn_wc_contex
SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, child_abspath, FALSE,
iterpool));
if (kind == svn_wc__db_kind_dir)
- SVN_ERR(svn_wc__release_write_lock(wc_ctx, child_abspath, iterpool));
+ {
+ svn_error_t *err = svn_wc__release_write_lock(wc_ctx, child_abspath, iterpool);
+
+ if (err && err->apr_err == SVN_ERR_WC_NOT_LOCKED)
+ svn_error_clear(err);
+ else
+ SVN_ERR(err);
+ }
}
- SVN_ERR(svn_wc__db_temp_own_lock(&locked_here, wc_ctx->db, local_abspath,
- iterpool));
- if (locked_here)
- SVN_ERR(svn_wc__db_wclock_remove(wc_ctx->db, local_abspath, iterpool));
+ SVN_ERR(svn_wc__db_wclock_release(wc_ctx->db, local_abspath, iterpool));
svn_pool_destroy(iterpool);
+#else
+ SVN_ERR(svn_wc__db_wclock_release(wc_ctx->db, local_abspath, scratch_pool));
+#endif
+
return SVN_NO_ERROR;
}
@@ -1728,14 +1784,16 @@ svn_wc__call_with_write_lock(svn_wc__wit
void *baton,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
+ svn_boolean_t lock_anchor,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
svn_error_t *err1, *err2;
- SVN_ERR(svn_wc__acquire_write_lock(NULL, wc_ctx, local_abspath,
- scratch_pool, scratch_pool));
- err1 = func(baton, result_pool, scratch_pool);
- err2 = svn_wc__release_write_lock(wc_ctx, local_abspath, scratch_pool);
+ const char *lock_root_abspath;
+ SVN_ERR(svn_wc__acquire_write_lock(&lock_root_abspath, wc_ctx, local_abspath,
+ lock_anchor, scratch_pool, scratch_pool));
+ err1 = svn_error_return(func(baton, result_pool, scratch_pool));
+ err2 = svn_wc__release_write_lock(wc_ctx, lock_root_abspath, scratch_pool);
return svn_error_compose_create(err1, err2);
}