You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2010/12/29 22:12:38 UTC
svn commit: r1053735 [2/8] - in /subversion/branches/performance: ./ build/
build/ac-macros/ build/generator/ build/generator/swig/
contrib/client-side/svn_load_dirs/ notes/
subversion/bindings/javahl/native/ subversion/bindings/swig/
subversion/includ...
Modified: subversion/branches/performance/subversion/libsvn_client/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_client/util.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_client/util.c (original)
+++ subversion/branches/performance/subversion/libsvn_client/util.c Wed Dec 29 21:12:33 2010
@@ -34,6 +34,7 @@
#include "svn_wc.h"
#include "svn_client.h"
+#include "private/svn_client_private.h"
#include "private/svn_wc_private.h"
#include "client.h"
@@ -320,3 +321,25 @@ svn_cl__rev_default_to_peg(const svn_opt
return peg_revision;
return revision;
}
+
+svn_error_t *
+svn_client__assert_homogeneous_target_type(const apr_array_header_t *targets)
+{
+ svn_boolean_t wc_present = FALSE, url_present = FALSE;
+ int i;
+
+ for (i = 0; i < targets->nelts; ++i)
+ {
+ const char *target = APR_ARRAY_IDX(targets, i, const char *);
+ if (! svn_path_is_url(target))
+ wc_present = TRUE;
+ else
+ url_present = TRUE;
+ if (url_present && wc_present)
+ return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+ _("Cannot mix repository and working copy "
+ "targets"));
+ }
+
+ return SVN_NO_ERROR;
+}
Modified: subversion/branches/performance/subversion/libsvn_fs/fs-loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs/fs-loader.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs/fs-loader.c (original)
+++ subversion/branches/performance/subversion/libsvn_fs/fs-loader.c Wed Dec 29 21:12:33 2010
@@ -676,6 +676,7 @@ svn_fs_commit_txn(const char **conflict_
svn_fs_t *fs;
const char *fs_path;
+ *new_rev = SVN_INVALID_REVNUM;
SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
fs = svn_fs_root_fs(txn_root);
fs_path = svn_fs_path(fs, pool);
Modified: subversion/branches/performance/subversion/libsvn_fs_base/reps-strings.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_base/reps-strings.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_base/reps-strings.c (original)
+++ subversion/branches/performance/subversion/libsvn_fs_base/reps-strings.c Wed Dec 29 21:12:33 2010
@@ -906,10 +906,12 @@ txn_body_read_rep(void *baton, trail_t *
{
representation_t *rep;
- svn_checksum_final(&args->rb->md5_checksum,
- args->rb->md5_checksum_ctx, trail->pool);
- svn_checksum_final(&args->rb->sha1_checksum,
- args->rb->sha1_checksum_ctx, trail->pool);
+ SVN_ERR(svn_checksum_final(&args->rb->md5_checksum,
+ args->rb->md5_checksum_ctx,
+ trail->pool));
+ SVN_ERR(svn_checksum_final(&args->rb->sha1_checksum,
+ args->rb->sha1_checksum_ctx,
+ trail->pool));
args->rb->checksum_finalized = TRUE;
SVN_ERR(svn_fs_bdb__read_rep(&rep, args->rb->fs,
Modified: subversion/branches/performance/subversion/libsvn_fs_base/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_base/tree.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_base/tree.c (original)
+++ subversion/branches/performance/subversion/libsvn_fs_base/tree.c Wed Dec 29 21:12:33 2010
@@ -5365,9 +5365,10 @@ crawl_directory_for_mergeinfo(svn_fs_t *
void *val;
svn_pool_clear(iterpool);
apr_hash_this(hi, &key, NULL, &val);
- crawl_directory_for_mergeinfo(fs, val,
- svn_fspath__join(node_path, key, iterpool),
- result_catalog, iterpool);
+ SVN_ERR(crawl_directory_for_mergeinfo(fs, val,
+ svn_fspath__join(node_path, key,
+ iterpool),
+ result_catalog, iterpool));
}
svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
Modified: subversion/branches/performance/subversion/libsvn_fs_base/util/fs_skels.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_base/util/fs_skels.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_base/util/fs_skels.c (original)
+++ subversion/branches/performance/subversion/libsvn_fs_base/util/fs_skels.c Wed Dec 29 21:12:33 2010
@@ -1071,14 +1071,14 @@ svn_fs_base__unparse_representation_skel
/* SHA1 */
if ((format >= SVN_FS_BASE__MIN_REP_SHARING_FORMAT) && rep->sha1_checksum)
- prepend_checksum(header_skel, rep->sha1_checksum, pool);
+ SVN_ERR(prepend_checksum(header_skel, rep->sha1_checksum, pool));
/* MD5 */
{
svn_checksum_t *md5_checksum = rep->md5_checksum;
if (! md5_checksum)
md5_checksum = svn_checksum_create(svn_checksum_md5, pool);
- prepend_checksum(header_skel, md5_checksum, pool);
+ SVN_ERR(prepend_checksum(header_skel, md5_checksum, pool));
}
/* TXN */
Modified: subversion/branches/performance/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_fs/fs_fs.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/performance/subversion/libsvn_fs_fs/fs_fs.c Wed Dec 29 21:12:33 2010
@@ -3844,7 +3844,8 @@ rep_read_contents(void *baton,
svn_checksum_t *md5_checksum;
rb->checksum_finalized = TRUE;
- svn_checksum_final(&md5_checksum, rb->md5_checksum_ctx, rb->pool);
+ SVN_ERR(svn_checksum_final(&md5_checksum, rb->md5_checksum_ctx,
+ rb->pool));
if (!svn_checksum_match(md5_checksum, rb->md5_checksum))
return svn_error_createf
(SVN_ERR_FS_CORRUPT, NULL,
@@ -5800,9 +5801,20 @@ rep_write_contents_close(void *baton)
/* Check and see if we already have a representation somewhere that's
identical to the one we just wrote out. */
if (ffd->rep_sharing_allowed)
- /* ### TODO: ignore errors opening the DB (issue #3506) * */
- SVN_ERR(svn_fs_fs__get_rep_reference(&old_rep, b->fs, rep->sha1_checksum,
- b->parent_pool));
+ {
+ svn_error_t *err;
+ err = svn_fs_fs__get_rep_reference(&old_rep, b->fs, rep->sha1_checksum,
+ b->parent_pool);
+ if (err)
+ {
+ /* Something's wrong with the rep-sharing index. We can continue
+ without rep-sharing, but warn.
+ */
+ (b->fs->warning)(b->fs->warning_baton, err);
+ svn_error_clear(err);
+ old_rep = NULL;
+ }
+ }
else
old_rep = NULL;
@@ -6029,7 +6041,7 @@ write_hash_rep(svn_filesize_t *size,
SVN_ERR(svn_hash_write2(hash, stream, SVN_HASH_TERMINATOR, pool));
/* Store the results. */
- svn_checksum_final(checksum, whb->checksum_ctx, pool);
+ SVN_ERR(svn_checksum_final(checksum, whb->checksum_ctx, pool));
*size = whb->size;
return svn_stream_printf(whb->stream, pool, "ENDREP\n");
@@ -6585,13 +6597,19 @@ commit_body(void *baton, apr_pool_t *poo
/* Update the 'current' file. */
SVN_ERR(write_final_current(cb->fs, cb->txn->id, new_rev, start_node_id,
start_copy_id, pool));
+
+ /* At this point the new revision is committed and globally visible
+ so let the caller know it succeeded by giving it the new revision
+ number, which fulfills svn_fs_commit_txn() contract. Any errors
+ after this point do not change the fact that a new revision was
+ created. */
+ *cb->new_rev_p = new_rev;
+
ffd->youngest_rev_cache = new_rev;
/* Remove this transaction directory. */
SVN_ERR(svn_fs_fs__purge_txn(cb->fs, cb->txn->id, pool));
- *cb->new_rev_p = new_rev;
-
return SVN_NO_ERROR;
}
@@ -6759,7 +6777,8 @@ svn_fs_fs__commit(svn_revnum_t *new_rev_
if (ffd->rep_sharing_allowed)
{
- /* ### TODO: ignore errors opening the DB (issue #3506) * */
+ /* At this point, *NEW_REV_P has been set, so errors here won't affect
+ the success of the commit. (See svn_fs_commit_txn().) */
SVN_ERR(svn_fs_fs__open_rep_cache(fs, pool));
SVN_ERR(svn_sqlite__with_transaction(ffd->rep_cache_db,
commit_sqlite_txn_callback,
@@ -7990,8 +8009,8 @@ pack_shard(const char *revs_dir,
SVN_ERR(svn_io_stat(&finfo, path, APR_FINFO_SIZE, iterpool));
/* Update the manifest. */
- svn_stream_printf(manifest_stream, iterpool, "%" APR_OFF_T_FMT "\n",
- next_offset);
+ SVN_ERR(svn_stream_printf(manifest_stream, iterpool, "%" APR_OFF_T_FMT
+ "\n", next_offset));
next_offset += finfo.size;
/* Copy all the bits from the rev file to the end of the pack file. */
@@ -8099,6 +8118,22 @@ struct pack_baton
void *cancel_baton;
};
+
+/* The work-horse for svn_fs_fs__pack, called with the FS write lock.
+ This implements the svn_fs_fs__with_write_lock() 'body' callback
+ type. BATON is a 'struct pack_baton *'.
+
+ WARNING: if you add a call to this function, please note:
+ The code currently assumes that any piece of code running with
+ the write-lock set can rely on the ffd->min_unpacked_rev and
+ ffd->min_unpacked_revprop caches to be up-to-date (and, by
+ extension, on not having to use a retry when calling
+ svn_fs_fs__path_rev_absolute() and friends). If you add a call
+ to this function, consider whether you have to call
+ update_min_unpacked_rev() and update_min_unpacked_revprop()
+ afterwards.
+ See this thread: http://thread.gmane.org/1291206765.3782.3309.camel@edith
+ */
static svn_error_t *
pack_body(void *baton,
apr_pool_t *pool)
Modified: subversion/branches/performance/subversion/libsvn_fs_fs/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_fs/lock.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_fs/lock.c (original)
+++ subversion/branches/performance/subversion/libsvn_fs_fs/lock.c Wed Dec 29 21:12:33 2010
@@ -60,16 +60,18 @@
/*** Generic helper functions. ***/
-/* Return the MD5 hash of STR. */
-static const char *
-make_digest(const char *str,
+/* Set *DIGEST to the MD5 hash of STR. */
+static svn_error_t *
+make_digest(const char **digest,
+ const char *str,
apr_pool_t *pool)
{
svn_checksum_t *checksum;
- svn_checksum(&checksum, svn_checksum_md5, str, strlen(str), pool);
+ SVN_ERR(svn_checksum(&checksum, svn_checksum_md5, str, strlen(str), pool));
- return svn_checksum_to_cstring_display(checksum, pool);
+ *digest = svn_checksum_to_cstring_display(checksum, pool);
+ return SVN_NO_ERROR;
}
@@ -134,18 +136,22 @@ digest_path_from_digest(const char *fs_p
}
-/* Return the path to the lock/entries digest file associate with
- PATH, where PATH is the path to the lock file or lock entries file
+/* Set *DIGEST_PATH to the path to the lock/entries digest file associate
+ with PATH, where PATH is the path to the lock file or lock entries file
in FS. */
-static const char *
-digest_path_from_path(const char *fs_path,
+static svn_error_t *
+digest_path_from_path(const char **digest_path,
+ const char *fs_path,
const char *path,
apr_pool_t *pool)
{
- const char *digest = make_digest(path, pool);
- return svn_dirent_join_many(pool, fs_path, PATH_LOCKS_DIR,
- apr_pstrmemdup(pool, digest, DIGEST_SUBDIR_LEN),
- digest, NULL);
+ const char *digest;
+ SVN_ERR(make_digest(&digest, path, pool));
+ *digest_path = svn_dirent_join_many(pool, fs_path, PATH_LOCKS_DIR,
+ apr_pstrmemdup(pool, digest,
+ DIGEST_SUBDIR_LEN),
+ digest, NULL);
+ return SVN_NO_ERROR;
}
@@ -362,7 +368,8 @@ set_lock(const char *fs_path,
/* Calculate the DIGEST_PATH for the currently FS path, and then
get its DIGEST_FILE basename. */
- digest_path = digest_path_from_path(fs_path, this_path->data, subpool);
+ SVN_ERR(digest_path_from_path(&digest_path, fs_path, this_path->data,
+ subpool));
digest_file = svn_dirent_basename(digest_path, subpool);
SVN_ERR(read_digest_file(&this_children, &this_lock, fs_path,
@@ -389,10 +396,10 @@ set_lock(const char *fs_path,
digest_path, perms_reference, subpool));
/* Prep for next iteration, or bail if we're done. */
- if (svn_dirent_is_root(this_path->data, this_path->len))
+ if (svn_uri_is_root(this_path->data, this_path->len))
break;
svn_stringbuf_set(this_path,
- svn_dirent_dirname(this_path->data, subpool));
+ svn_fspath__dirname(this_path->data, subpool));
}
svn_pool_destroy(subpool);
@@ -424,7 +431,8 @@ delete_lock(svn_fs_t *fs,
/* Calculate the DIGEST_PATH for the currently FS path, and then
get its DIGEST_FILE basename. */
- digest_path = digest_path_from_path(fs->path, this_path->data, subpool);
+ SVN_ERR(digest_path_from_path(&digest_path, fs->path, this_path->data,
+ subpool));
digest_file = svn_dirent_basename(digest_path, subpool);
SVN_ERR(read_digest_file(&this_children, &this_lock, fs->path,
@@ -456,10 +464,10 @@ delete_lock(svn_fs_t *fs,
}
/* Prep for next iteration, or bail if we're done. */
- if (svn_dirent_is_root(this_path->data, this_path->len))
+ if (svn_uri_is_root(this_path->data, this_path->len))
break;
svn_stringbuf_set(this_path,
- svn_dirent_dirname(this_path->data, subpool));
+ svn_fspath__dirname(this_path->data, subpool));
}
svn_pool_destroy(subpool);
@@ -478,7 +486,9 @@ get_lock(svn_lock_t **lock_p,
apr_pool_t *pool)
{
svn_lock_t *lock;
- const char *digest_path = digest_path_from_path(fs->path, path, pool);
+ const char *digest_path;
+
+ SVN_ERR(digest_path_from_path(&digest_path, fs->path, path, pool));
SVN_ERR(read_digest_file(NULL, &lock, fs->path, digest_path, pool));
if (! lock)
@@ -702,7 +712,8 @@ svn_fs_fs__allow_locked_operation(const
if (recurse)
{
/* Discover all locks at or below the path. */
- const char *digest_path = digest_path_from_path(fs->path, path, pool);
+ const char *digest_path;
+ SVN_ERR(digest_path_from_path(&digest_path, fs->path, path, pool));
SVN_ERR(walk_locks(fs, digest_path, get_locks_callback,
fs, have_write_lock, pool));
}
@@ -1052,7 +1063,7 @@ svn_fs_fs__get_locks(svn_fs_t *fs,
glfb.get_locks_baton = get_locks_baton;
/* Get the top digest path in our tree of interest, and then walk it. */
- digest_path = digest_path_from_path(fs->path, path, pool);
+ SVN_ERR(digest_path_from_path(&digest_path, fs->path, path, pool));
SVN_ERR(walk_locks(fs, digest_path, get_locks_filter_func, &glfb,
FALSE, pool));
return SVN_NO_ERROR;
Modified: subversion/branches/performance/subversion/libsvn_fs_fs/rep-cache.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_fs/rep-cache.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_fs/rep-cache.c (original)
+++ subversion/branches/performance/subversion/libsvn_fs_fs/rep-cache.c Wed Dec 29 21:12:33 2010
@@ -72,8 +72,9 @@ svn_fs_fs__open_rep_cache(svn_fs_t *fs,
apr_pool_t *pool)
{
fs_fs_data_t *ffd = fs->fsap_data;
- return svn_error_return(svn_atomic__init_once(&ffd->rep_cache_db_opened,
- open_rep_cache, fs, pool));
+ svn_error_t *err = svn_atomic__init_once(&ffd->rep_cache_db_opened,
+ open_rep_cache, fs, pool);
+ return svn_error_quick_wrap(err, _("Couldn't open rep-cache database"));
}
svn_error_t *
Modified: subversion/branches/performance/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_fs/tree.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/performance/subversion/libsvn_fs_fs/tree.c Wed Dec 29 21:12:33 2010
@@ -1447,18 +1447,18 @@ merge(svn_stringbuf_t *conflict_p,
a modification. In any of these cases, flag a conflict. */
if (s_entry == NULL || t_entry == NULL)
return conflict_err(conflict_p,
- svn_dirent_join(target_path,
- a_entry->name,
- iterpool));
+ svn_fspath__join(target_path,
+ a_entry->name,
+ iterpool));
/* If any of the three entries is of type file, flag a conflict. */
if (s_entry->kind == svn_node_file
|| t_entry->kind == svn_node_file
|| a_entry->kind == svn_node_file)
return conflict_err(conflict_p,
- svn_dirent_join(target_path,
- a_entry->name,
- iterpool));
+ svn_fspath__join(target_path,
+ a_entry->name,
+ iterpool));
/* If either SOURCE-ENTRY or TARGET-ENTRY is not a direct
modification of ANCESTOR-ENTRY, declare a conflict. */
@@ -1471,9 +1471,9 @@ merge(svn_stringbuf_t *conflict_p,
|| strcmp(svn_fs_fs__id_copy_id(t_entry->id),
svn_fs_fs__id_copy_id(a_entry->id)) != 0)
return conflict_err(conflict_p,
- svn_dirent_join(target_path,
- a_entry->name,
- iterpool));
+ svn_fspath__join(target_path,
+ a_entry->name,
+ iterpool));
/* Direct modifications were made to the directory
ANCESTOR-ENTRY in both SOURCE and TARGET. Recursively
@@ -1484,7 +1484,7 @@ merge(svn_stringbuf_t *conflict_p,
t_entry->id, iterpool));
SVN_ERR(svn_fs_fs__dag_get_node(&a_ent_node, fs,
a_entry->id, iterpool));
- new_tpath = svn_dirent_join(target_path, t_entry->name, iterpool);
+ new_tpath = svn_fspath__join(target_path, t_entry->name, iterpool);
SVN_ERR(merge(conflict_p, new_tpath,
t_ent_node, s_ent_node, a_ent_node,
txn_id,
@@ -1520,9 +1520,9 @@ merge(svn_stringbuf_t *conflict_p,
/* If NAME exists in TARGET, declare a conflict. */
if (t_entry)
return conflict_err(conflict_p,
- svn_dirent_join(target_path,
- t_entry->name,
- iterpool));
+ svn_fspath__join(target_path,
+ t_entry->name,
+ iterpool));
SVN_ERR(svn_fs_fs__dag_get_node(&s_ent_node, fs,
s_entry->id, iterpool));
Modified: subversion/branches/performance/subversion/libsvn_ra/compat.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_ra/compat.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_ra/compat.c (original)
+++ subversion/branches/performance/subversion/libsvn_ra/compat.c Wed Dec 29 21:12:33 2010
@@ -763,12 +763,12 @@ svn_ra__file_revs_from_log(svn_ra_sessio
currpool = lastpool;
lastpool = tmppool;
- svn_stream_close(last_stream);
+ SVN_ERR(svn_stream_close(last_stream));
last_stream = stream;
last_props = props;
}
- svn_stream_close(last_stream);
+ SVN_ERR(svn_stream_close(last_stream));
svn_pool_destroy(currpool);
svn_pool_destroy(lastpool);
Modified: subversion/branches/performance/subversion/libsvn_ra/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_ra/util.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_ra/util.c (original)
+++ subversion/branches/performance/subversion/libsvn_ra/util.c Wed Dec 29 21:12:33 2010
@@ -25,8 +25,10 @@
/*** Includes. ***/
#include <apr_pools.h>
+#include <apr_network_io.h>
#include "svn_types.h"
+#include "svn_pools.h"
#include "svn_error.h"
#include "svn_error_codes.h"
#include "svn_dirent_uri.h"
@@ -70,3 +72,171 @@ svn_ra__assert_mergeinfo_capable_server(
}
return SVN_NO_ERROR;
}
+
+/* Does ERR mean "the current value of the revprop isn't equal to
+ the *OLD_VALUE_P you gave me"?
+ */
+static svn_boolean_t is_atomicity_error(svn_error_t *err)
+{
+ return svn_error_find_cause(err, SVN_ERR_FS_PROP_BASEVALUE_MISMATCH) != NULL;
+}
+
+svn_error_t *
+svn_ra__release_operational_lock(svn_ra_session_t *session,
+ const char *lock_revprop_name,
+ const svn_string_t *mylocktoken,
+ apr_pool_t *scratch_pool)
+{
+ svn_string_t *reposlocktoken;
+ svn_boolean_t be_atomic;
+
+ SVN_ERR(svn_ra_has_capability(session, &be_atomic,
+ SVN_RA_CAPABILITY_ATOMIC_REVPROPS,
+ scratch_pool));
+ SVN_ERR(svn_ra_rev_prop(session, 0, lock_revprop_name,
+ &reposlocktoken, scratch_pool));
+ if (reposlocktoken && svn_string_compare(reposlocktoken, mylocktoken))
+ {
+ svn_error_t *err;
+
+ err = svn_ra_change_rev_prop2(session, 0, lock_revprop_name,
+ be_atomic ? &mylocktoken : NULL, NULL,
+ scratch_pool);
+ if (is_atomicity_error(err))
+ return svn_error_createf(err->apr_err, err,
+ _("Lock was stolen by '%s'; unable to "
+ "remove it"), reposlocktoken->data);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra__get_operational_lock(const svn_string_t **lock_string_p,
+ const svn_string_t **stolen_lock_p,
+ svn_ra_session_t *session,
+ const char *lock_revprop_name,
+ svn_boolean_t steal_lock,
+ int num_retries,
+ svn_ra__lock_retry_func_t retry_func,
+ void *retry_baton,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *pool)
+{
+ char hostname_str[APRMAXHOSTLEN + 1] = { 0 };
+ svn_string_t *mylocktoken, *reposlocktoken;
+ apr_status_t apr_err;
+ svn_boolean_t be_atomic;
+ apr_pool_t *subpool;
+ int i;
+
+ *lock_string_p = NULL;
+ if (stolen_lock_p)
+ *stolen_lock_p = NULL;
+
+ SVN_ERR(svn_ra_has_capability(session, &be_atomic,
+ SVN_RA_CAPABILITY_ATOMIC_REVPROPS, pool));
+
+ /* We build a lock token from the local hostname and a UUID. */
+ apr_err = apr_gethostname(hostname_str, sizeof(hostname_str), pool);
+ if (apr_err)
+ return svn_error_wrap_apr(apr_err,
+ _("Unable to determine local hostname"));
+ mylocktoken = svn_string_createf(pool, "%s:%s", hostname_str,
+ svn_uuid_generate(pool));
+
+ /* Ye Olde Retry Loope */
+ subpool = svn_pool_create(pool);
+
+ for (i = 0; i < num_retries; ++i)
+ {
+ svn_error_t *err;
+ const svn_string_t *unset = NULL;
+
+ svn_pool_clear(subpool);
+
+ /* Check for cancellation. If we're cancelled, don't leave a
+ stray lock behind! */
+ if (cancel_func)
+ {
+ err = cancel_func(cancel_baton);
+ if (err && err->apr_err == SVN_ERR_CANCELLED)
+ return svn_error_compose_create(
+ svn_ra__release_operational_lock(session,
+ lock_revprop_name,
+ mylocktoken,
+ subpool),
+ err);
+ SVN_ERR(err);
+ }
+
+ /* Ask the repository for the value of the LOCK_REVPROP_NAME. */
+ SVN_ERR(svn_ra_rev_prop(session, 0, lock_revprop_name,
+ &reposlocktoken, subpool));
+
+ /* Did we get a value from the repository? We'll check to see
+ if it matches our token. If so, we call it success. If not
+ and we're told to steal locks, we remember the existing lock
+ token and fall through to the locking code; othewise, we
+ sleep and retry. */
+ if (reposlocktoken)
+ {
+ if (svn_string_compare(reposlocktoken, mylocktoken))
+ {
+ *lock_string_p = mylocktoken;
+ return SVN_NO_ERROR;
+ }
+ else if (! steal_lock)
+ {
+ if (retry_func)
+ SVN_ERR(retry_func(retry_baton, reposlocktoken, subpool));
+ apr_sleep(apr_time_from_sec(1));
+ continue;
+ }
+ else
+ {
+ if (stolen_lock_p)
+ *stolen_lock_p = svn_string_dup(reposlocktoken, pool);
+ unset = reposlocktoken;
+ }
+ }
+
+ /* No lock value in the repository, or we plan to steal it?
+ Well, if we've got a spare iteration, we'll try to set the
+ lock. (We use the spare iteration to verify that we still
+ have the lock after setting it.) */
+ if (i < num_retries - 1)
+ {
+ /* Except in the very last iteration, try to set the lock. */
+ err = svn_ra_change_rev_prop2(session, 0, lock_revprop_name,
+ be_atomic ? &unset : NULL,
+ mylocktoken, subpool);
+
+ if (be_atomic && err && is_atomicity_error(err))
+ {
+ /* Someone else has the lock. No problem, we'll loop again. */
+ svn_error_clear(err);
+ }
+ else if (be_atomic && err == SVN_NO_ERROR)
+ {
+ /* Yay! We have the lock! However, for compatibility
+ with concurrent processes that don't support
+ atomicity, loop anyway to double-check that they
+ haven't overwritten our lock.
+ */
+ continue;
+ }
+ else
+ {
+ /* We have a genuine error, or aren't atomic and need
+ to loop. */
+ SVN_ERR(err);
+ }
+ }
+ }
+
+ return svn_error_createf(APR_EINVAL, NULL,
+ _("Couldn't get lock on destination repos "
+ "after %d attempts"), i);
+}
Modified: subversion/branches/performance/subversion/libsvn_ra_local/ra_plugin.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_ra_local/ra_plugin.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_ra_local/ra_plugin.c (original)
+++ subversion/branches/performance/subversion/libsvn_ra_local/ra_plugin.c Wed Dec 29 21:12:33 2010
@@ -416,7 +416,7 @@ svn_ra_local__get_schemes(apr_pool_t *po
/* Do nothing.
*
- * Why is this acceptable? As of now, FS warnings are used for only
+ * Why is this acceptable? FS warnings used to be used for only
* two things: failures to close BDB repositories and failures to
* interact with memcached in FSFS (new in 1.6). In 1.5 and earlier,
* we did not call svn_fs_set_warning_func in ra_local, which means
@@ -433,6 +433,9 @@ static void
ignore_warnings(void *baton,
svn_error_t *err)
{
+#ifdef SVN_DEBUG
+ SVN_DBG(("Ignoring FS warning %d\n", err ? err->apr_err : 0));
+#endif
return;
}
Modified: subversion/branches/performance/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_ra_serf/commit.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/branches/performance/subversion/libsvn_ra_serf/commit.c Wed Dec 29 21:12:33 2010
@@ -525,9 +525,9 @@ get_version_url(const char **checked_in_
propfind_url = session->repos_url.path;
}
- svn_ra_serf__deliver_props(&propfind_ctx, props, session, conn,
- propfind_url, base_revision, "0",
- checked_in_props, FALSE, NULL, pool);
+ SVN_ERR(svn_ra_serf__deliver_props(&propfind_ctx, props, session, conn,
+ propfind_url, base_revision, "0",
+ checked_in_props, FALSE, NULL, pool));
SVN_ERR(svn_ra_serf__wait_for_props(propfind_ctx, session, pool));
@@ -2401,9 +2401,9 @@ svn_ra_serf__change_rev_prop(svn_ra_sess
props = apr_hash_make(pool);
propfind_ctx = NULL;
- svn_ra_serf__deliver_props(&propfind_ctx, props, commit->session,
- commit->conn, vcc_url, rev, "0",
- checked_in_props, FALSE, NULL, pool);
+ SVN_ERR(svn_ra_serf__deliver_props(&propfind_ctx, props, commit->session,
+ commit->conn, vcc_url, rev, "0",
+ checked_in_props, FALSE, NULL, pool));
SVN_ERR(svn_ra_serf__wait_for_props(propfind_ctx, commit->session, pool));
Modified: subversion/branches/performance/subversion/libsvn_ra_serf/options.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_ra_serf/options.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_ra_serf/options.c (original)
+++ subversion/branches/performance/subversion/libsvn_ra_serf/options.c Wed Dec 29 21:12:33 2010
@@ -494,8 +494,9 @@ svn_ra_serf__exchange_capabilities(svn_r
svn_error_t *err;
/* This routine automatically fills in serf_sess->capabilities */
- svn_ra_serf__create_options_req(&opt_ctx, serf_sess, serf_sess->conns[0],
- serf_sess->repos_url.path, pool);
+ SVN_ERR(svn_ra_serf__create_options_req(&opt_ctx, serf_sess,
+ serf_sess->conns[0],
+ serf_sess->repos_url.path, pool));
err = svn_ra_serf__context_run_wait(
svn_ra_serf__get_options_done_ptr(opt_ctx), serf_sess, pool);
Modified: subversion/branches/performance/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_ra_serf/property.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/branches/performance/subversion/libsvn_ra_serf/property.c Wed Dec 29 21:12:33 2010
@@ -990,8 +990,9 @@ svn_ra_serf__get_baseline_info(const cha
{
svn_ra_serf__options_context_t *opt_ctx;
- svn_ra_serf__create_options_req(&opt_ctx, session, conn,
- session->repos_url.path, pool);
+ SVN_ERR(svn_ra_serf__create_options_req(&opt_ctx, session, conn,
+ session->repos_url.path,
+ pool));
SVN_ERR(svn_ra_serf__context_run_wait(
svn_ra_serf__get_options_done_ptr(opt_ctx), session, pool));
Modified: subversion/branches/performance/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_ra_serf/ra_serf.h?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/performance/subversion/libsvn_ra_serf/ra_serf.h Wed Dec 29 21:12:33 2010
@@ -883,10 +883,12 @@ svn_ra_serf__define_ns(svn_ra_serf__ns_t
* Look up @a name in the @a ns_list list for previously declared namespace
* definitions.
*
- * @return @a svn_ra_serf__dav_props_t tuple representing the expanded name.
+ * Return (in @a *returned_prop_name) @a svn_ra_serf__dav_props_t tuple
+ * representing the expanded name.
*/
-svn_ra_serf__dav_props_t
-svn_ra_serf__expand_ns(svn_ra_serf__ns_t *ns_list,
+void
+svn_ra_serf__expand_ns(svn_ra_serf__dav_props_t *returned_prop_name,
+ svn_ra_serf__ns_t *ns_list,
const char *name);
/*
Modified: subversion/branches/performance/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_ra_serf/serf.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/performance/subversion/libsvn_ra_serf/serf.c Wed Dec 29 21:12:33 2010
@@ -600,9 +600,10 @@ fetch_path_props(svn_ra_serf__propfind_c
*/
if (!SVN_IS_VALID_REVNUM(revision))
{
- svn_ra_serf__deliver_props(&prop_ctx, props, session, session->conns[0],
- path, revision, "0", desired_props, TRUE,
- NULL, session->pool);
+ SVN_ERR(svn_ra_serf__deliver_props(&prop_ctx, props, session,
+ session->conns[0], path, revision,
+ "0", desired_props, TRUE, NULL,
+ session->pool));
}
else
{
@@ -619,10 +620,10 @@ fetch_path_props(svn_ra_serf__propfind_c
prop_ctx = NULL;
path = svn_path_url_add_component2(basecoll_url, relative_url, pool);
revision = SVN_INVALID_REVNUM;
- svn_ra_serf__deliver_props(&prop_ctx, props, session, session->conns[0],
- path, revision, "0",
- desired_props, TRUE,
- NULL, session->pool);
+ SVN_ERR(svn_ra_serf__deliver_props(&prop_ctx, props, session,
+ session->conns[0], path, revision,
+ "0", desired_props, TRUE, NULL,
+ session->pool));
}
if (prop_ctx)
Modified: subversion/branches/performance/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_ra_serf/update.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/performance/subversion/libsvn_ra_serf/update.c Wed Dec 29 21:12:33 2010
@@ -1189,10 +1189,11 @@ fetch_file(report_context_t *ctx, report
info->propfind = NULL;
if (info->fetch_props)
{
- svn_ra_serf__deliver_props(&info->propfind, info->props,
- ctx->sess, conn,
- info->url, info->target_rev, "0", all_props,
- FALSE, &ctx->done_propfinds, info->dir->pool);
+ SVN_ERR(svn_ra_serf__deliver_props(&info->propfind, info->props,
+ ctx->sess, conn, info->url,
+ info->target_rev, "0", all_props,
+ FALSE, &ctx->done_propfinds,
+ info->dir->pool));
SVN_ERR_ASSERT(info->propfind);
@@ -1743,12 +1744,14 @@ end_report(svn_ra_serf__xml_parser_t *pa
/* Unconditionally set fetch_props now. */
info->dir->fetch_props = TRUE;
- svn_ra_serf__deliver_props(&info->dir->propfind, info->dir->props,
- ctx->sess,
- ctx->sess->conns[ctx->sess->cur_conn],
- info->dir->url, info->dir->target_rev,
- "0", all_props, FALSE,
- &ctx->done_propfinds, info->dir->pool);
+ SVN_ERR(svn_ra_serf__deliver_props(&info->dir->propfind,
+ info->dir->props, ctx->sess,
+ ctx->sess->conns[ctx->sess->cur_conn],
+ info->dir->url,
+ info->dir->target_rev, "0",
+ all_props, FALSE,
+ &ctx->done_propfinds,
+ info->dir->pool));
SVN_ERR_ASSERT(info->dir->propfind);
Modified: subversion/branches/performance/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_ra_serf/util.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/performance/subversion/libsvn_ra_serf/util.c Wed Dec 29 21:12:33 2010
@@ -1171,7 +1171,7 @@ start_xml(void *userData, const char *ra
svn_ra_serf__define_ns(&parser->state->ns_list, attrs, parser->state->pool);
- name = svn_ra_serf__expand_ns(parser->state->ns_list, raw_name);
+ svn_ra_serf__expand_ns(&name, parser->state->ns_list, raw_name);
parser->error = parser->start(parser, parser->user_data, name, attrs);
}
@@ -1185,7 +1185,7 @@ end_xml(void *userData, const char *raw_
if (parser->error)
return;
- name = svn_ra_serf__expand_ns(parser->state->ns_list, raw_name);
+ svn_ra_serf__expand_ns(&name, parser->state->ns_list, raw_name);
parser->error = parser->end(parser, parser->user_data, name);
}
Modified: subversion/branches/performance/subversion/libsvn_ra_serf/xml.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_ra_serf/xml.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_ra_serf/xml.c (original)
+++ subversion/branches/performance/subversion/libsvn_ra_serf/xml.c Wed Dec 29 21:12:33 2010
@@ -86,8 +86,9 @@ svn_ra_serf__define_ns(svn_ra_serf__ns_t
* Look up NAME in the NS_LIST list for previously declared namespace
* definitions and return a DAV_PROPS_T-tuple that has values.
*/
-svn_ra_serf__dav_props_t
-svn_ra_serf__expand_ns(svn_ra_serf__ns_t *ns_list,
+void
+svn_ra_serf__expand_ns(svn_ra_serf__dav_props_t *returned_prop_name,
+ svn_ra_serf__ns_t *ns_list,
const char *name)
{
const char *colon;
@@ -120,7 +121,8 @@ svn_ra_serf__expand_ns(svn_ra_serf__ns_t
prop_name.name = name;
}
- return prop_name;
+ *returned_prop_name = prop_name;
+ return;
}
void
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=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/branches/performance/subversion/libsvn_ra_svn/client.c Wed Dec 29 21:12:33 2010
@@ -1063,7 +1063,7 @@ static svn_error_t *ra_svn_get_file(svn_
svn_checksum_t *checksum;
const char *hex_digest;
- svn_checksum_final(&checksum, checksum_ctx, pool);
+ SVN_ERR(svn_checksum_final(&checksum, checksum_ctx, pool));
hex_digest = svn_checksum_to_cstring_display(checksum, pool);
if (strcmp(hex_digest, expected_checksum) != 0)
return svn_error_createf
Modified: subversion/branches/performance/subversion/libsvn_repos/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_repos/commit.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_repos/commit.c (original)
+++ subversion/branches/performance/subversion/libsvn_repos/commit.c Wed Dec 29 21:12:33 2010
@@ -38,6 +38,7 @@
#include "svn_props.h"
#include "repos.h"
#include "svn_private_config.h"
+#include "private/svn_repos_private.h"
@@ -644,7 +645,68 @@ change_dir_prop(void *dir_baton,
name, value, pool);
}
+const char *
+svn_repos__post_commit_error_str(svn_error_t *err,
+ apr_pool_t *pool)
+{
+ svn_error_t *hook_err1, *hook_err2;
+ const char *msg;
+
+ if (! err)
+ return _("(no error)");
+
+ err = svn_error_purge_tracing(err);
+
+ /* hook_err1 is the SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED wrapped
+ error from the post-commit script, if any, and hook_err2 should
+ be the original error, but be defensive and handle a case where
+ SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED doesn't wrap an error. */
+ hook_err1 = svn_error_find_cause(err, SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED);
+ if (hook_err1 && hook_err1->child)
+ hook_err2 = hook_err1->child;
+ else
+ hook_err2 = hook_err1;
+
+ /* This implementation counts on svn_repos_fs_commit_txn() returning
+ svn_fs_commit_txn() as the parent error with a child
+ SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED error. If the parent error
+ is SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED then there was no error
+ in svn_fs_commit_txn().
+
+ The post-commit hook error message is already self describing, so
+ it can be dropped into an error message without any additional
+ text. */
+ if (hook_err1)
+ {
+ if (err == hook_err1)
+ {
+ if (hook_err2->message)
+ msg = apr_pstrdup(pool, hook_err2->message);
+ else
+ msg = _("post-commit hook failed with no error message");
+ }
+ else
+ {
+ msg = hook_err2->message
+ ? hook_err2->message
+ : _("post-commit hook failed with no error message.");
+ msg = apr_psprintf(
+ pool,
+ _("post commit FS processing had error '%s' and %s"),
+ err->message ? err->message : _("(no error message)"),
+ msg);
+ }
+ }
+ else
+ {
+ msg = apr_psprintf(pool,
+ _("post-commit FS processing had error '%s'."),
+ err->message ? err->message
+ : _("(no error message)"));
+ }
+ return msg;
+}
static svn_error_t *
close_edit(void *edit_baton,
@@ -654,7 +716,7 @@ close_edit(void *edit_baton,
svn_revnum_t new_revision = SVN_INVALID_REVNUM;
svn_error_t *err;
const char *conflict;
- char *post_commit_err = NULL;
+ const char *post_commit_err = NULL;
/* If no transaction has been created (ie. if open_root wasn't
called before close_edit), abort the operation here with an
@@ -667,51 +729,40 @@ close_edit(void *edit_baton,
err = svn_repos_fs_commit_txn(&conflict, eb->repos,
&new_revision, eb->txn, pool);
- if (err)
+ if (SVN_IS_VALID_REVNUM(new_revision))
{
- if (err->apr_err == SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED)
+ if (err)
{
/* If the error was in post-commit, then the commit itself
succeeded. In which case, save the post-commit warning
(to be reported back to the client, who will probably
display it as a warning) and clear the error. */
- if (err->child && err->child->message)
- {
- svn_error_t *warning_err = err->child;
-#ifdef SVN_ERR__TRACING
- /* Skip over any trace records. */
- while (warning_err->message != NULL
- && strcmp(warning_err->message, SVN_ERR__TRACED) == 0)
- warning_err = warning_err->child;
-#endif
- post_commit_err = apr_pstrdup(pool, warning_err->message);
- }
-
+ post_commit_err = svn_repos__post_commit_error_str(err, pool);
svn_error_clear(err);
err = SVN_NO_ERROR;
}
- else /* Got a real error -- one that stopped the commit */
- {
- /* ### todo: we should check whether it really was a conflict,
- and return the conflict info if so? */
+ }
+ else
+ {
+ /* ### todo: we should check whether it really was a conflict,
+ and return the conflict info if so? */
- /* If the commit failed, it's *probably* due to a conflict --
- that is, the txn being out-of-date. The filesystem gives us
- the ability to continue diddling the transaction and try
- again; but let's face it: that's not how the cvs or svn works
- from a user interface standpoint. Thus we don't make use of
- this fs feature (for now, at least.)
-
- So, in a nutshell: svn commits are an all-or-nothing deal.
- Each commit creates a new fs txn which either succeeds or is
- aborted completely. No second chances; the user simply
- needs to update and commit again :)
-
- We ignore the possible error result from svn_fs_abort_txn();
- it's more important to return the original error. */
- svn_error_clear(svn_fs_abort_txn(eb->txn, pool));
- return svn_error_return(err);
- }
+ /* If the commit failed, it's *probably* due to a conflict --
+ that is, the txn being out-of-date. The filesystem gives us
+ the ability to continue diddling the transaction and try
+ again; but let's face it: that's not how the cvs or svn works
+ from a user interface standpoint. Thus we don't make use of
+ this fs feature (for now, at least.)
+
+ So, in a nutshell: svn commits are an all-or-nothing deal.
+ Each commit creates a new fs txn which either succeeds or is
+ aborted completely. No second chances; the user simply
+ needs to update and commit again :)
+
+ We ignore the possible error result from svn_fs_abort_txn();
+ it's more important to return the original error. */
+ svn_error_clear(svn_fs_abort_txn(eb->txn, pool));
+ return svn_error_return(err);
}
/* Pass new revision information to the caller's callback. */
@@ -743,8 +794,8 @@ close_edit(void *edit_baton,
commit_info->author = author ? author->data : NULL;
commit_info->post_commit_err = post_commit_err;
err = (*eb->commit_callback)(commit_info,
- eb->commit_callback_baton,
- pool);
+ eb->commit_callback_baton,
+ pool);
}
}
Modified: subversion/branches/performance/subversion/libsvn_repos/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_repos/deprecated.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_repos/deprecated.c (original)
+++ subversion/branches/performance/subversion/libsvn_repos/deprecated.c Wed Dec 29 21:12:33 2010
@@ -718,7 +718,7 @@ svn_repos_load_fs2(svn_repos_t *repos,
apr_pool_t *pool)
{
return svn_repos_load_fs3(repos, dumpstream, uuid_action, parent_dir,
- use_pre_commit_hook, use_post_commit_hook,
+ use_pre_commit_hook, use_post_commit_hook, FALSE,
feedback_stream ? repos_notify_handler : NULL,
feedback_stream, cancel_func, cancel_baton, pool);
}
@@ -804,7 +804,7 @@ svn_repos_get_fs_build_parser2(const svn
apr_pool_t *pool)
{
return svn_repos_get_fs_build_parser3(parser, parse_baton, repos, use_history,
- uuid_action, parent_dir,
+ FALSE, uuid_action, parent_dir,
outstream ? repos_notify_handler : NULL,
outstream, pool);
}
Modified: subversion/branches/performance/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_repos/dump.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/performance/subversion/libsvn_repos/dump.c Wed Dec 29 21:12:33 2010
@@ -480,8 +480,8 @@ dump_node(struct edit_baton *eb,
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_hash_write_incremental(prophash, oldhash, propstream,
+ "PROPS-END", pool));
SVN_ERR(svn_stream_close(propstream));
proplen = propstring->len;
content_length += proplen;
@@ -907,7 +907,7 @@ write_revision_record(svn_stream_t *stre
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_hash_write2(props, propstream, "PROPS-END", pool));
SVN_ERR(svn_stream_close(propstream));
/* ### someday write a revision-content-checksum */
Modified: subversion/branches/performance/subversion/libsvn_repos/fs-wrap.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_repos/fs-wrap.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_repos/fs-wrap.c (original)
+++ subversion/branches/performance/subversion/libsvn_repos/fs-wrap.c Wed Dec 29 21:12:33 2010
@@ -33,6 +33,7 @@
#include "svn_time.h"
#include "repos.h"
#include "svn_private_config.h"
+#include "private/svn_repos_private.h"
#include "private/svn_utf_private.h"
@@ -45,25 +46,29 @@ svn_repos_fs_commit_txn(const char **con
svn_fs_txn_t *txn,
apr_pool_t *pool)
{
- svn_error_t *err;
+ svn_error_t *err, *err2;
const char *txn_name;
+ *new_rev = SVN_INVALID_REVNUM;
+
/* Run pre-commit hooks. */
SVN_ERR(svn_fs_txn_name(&txn_name, txn, pool));
SVN_ERR(svn_repos__hooks_pre_commit(repos, txn_name, pool));
/* Commit. */
- SVN_ERR(svn_fs_commit_txn(conflict_p, new_rev, txn, pool));
+ err = svn_fs_commit_txn(conflict_p, new_rev, txn, pool);
+ if (! SVN_IS_VALID_REVNUM(*new_rev))
+ return err;
- /* Run post-commit hooks. Notice that we're wrapping the error
- with a -specific- errorcode, so that our caller knows not to try
- and abort the transaction. */
- if ((err = svn_repos__hooks_post_commit(repos, *new_rev, pool)))
- return svn_error_create
- (SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED, err,
- _("Commit succeeded, but post-commit hook failed"));
+ /* Run post-commit hooks. */
+ if ((err2 = svn_repos__hooks_post_commit(repos, *new_rev, pool)))
+ {
+ err2 = svn_error_create
+ (SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED, err2,
+ _("Commit succeeded, but post-commit hook failed"));
+ }
- return SVN_NO_ERROR;
+ return svn_error_compose_create(err, err2);
}
@@ -152,15 +157,10 @@ svn_repos_fs_begin_txn_for_update(svn_fs
/*** Property wrappers ***/
-/* Validate that property NAME is valid for use in a Subversion
- repository; return SVN_ERR_REPOS_BAD_ARGS if it isn't. For some "svn:"
- properties, also validate the value, and return SVN_ERR_BAD_PROPERTY_VALUE
- if it is not valid.
-
- Use POOL for temporary allocations.
- */
-static svn_error_t *
-validate_prop(const char *name, const svn_string_t *value, apr_pool_t *pool)
+svn_error_t *
+svn_repos__validate_prop(const char *name,
+ const svn_string_t *value,
+ apr_pool_t *pool)
{
svn_prop_kind_t kind = svn_property_kind(NULL, name);
@@ -223,7 +223,7 @@ svn_repos_fs_change_node_prop(svn_fs_roo
apr_pool_t *pool)
{
/* Validate the property, then call the wrapped function. */
- SVN_ERR(validate_prop(name, value, pool));
+ SVN_ERR(svn_repos__validate_prop(name, value, pool));
return svn_fs_change_node_prop(root, path, name, value, pool);
}
@@ -238,7 +238,7 @@ svn_repos_fs_change_txn_props(svn_fs_txn
for (i = 0; i < txnprops->nelts; i++)
{
svn_prop_t *prop = &APR_ARRAY_IDX(txnprops, i, svn_prop_t);
- SVN_ERR(validate_prop(prop->name, prop->value, pool));
+ SVN_ERR(svn_repos__validate_prop(prop->name, prop->value, pool));
}
return svn_fs_change_txn_props(txn, txnprops, pool);
@@ -286,7 +286,7 @@ svn_repos_fs_change_rev_prop4(svn_repos_
const svn_string_t *old_value;
char action;
- SVN_ERR(validate_prop(name, new_value, pool));
+ SVN_ERR(svn_repos__validate_prop(name, new_value, pool));
/* Fetch OLD_VALUE for svn_fs_change_rev_prop2(). */
if (old_value_p)
Modified: subversion/branches/performance/subversion/libsvn_repos/hooks.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_repos/hooks.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_repos/hooks.c (original)
+++ subversion/branches/performance/subversion/libsvn_repos/hooks.c Wed Dec 29 21:12:33 2010
@@ -177,56 +177,14 @@ run_hook_cmd(svn_string_t **result,
apr_file_t *stdin_handle,
apr_pool_t *pool)
{
- apr_file_t *read_errhandle, *write_errhandle, *null_handle;
- apr_file_t *read_outhandle, *write_outhandle;
+ apr_file_t *null_handle;
apr_status_t apr_err;
svn_error_t *err;
apr_proc_t cmd_proc;
- /* Create a pipe to access stderr of the child. */
- apr_err = apr_file_pipe_create(&read_errhandle, &write_errhandle, pool);
- if (apr_err)
- return svn_error_wrap_apr
- (apr_err, _("Can't create pipe for hook '%s'"), cmd);
-
- /* Pipes are inherited by default, but we don't want that, since
- APR will duplicate the write end of the pipe for the child process.
- Not closing the read end is harmless, but if the write end is inherited,
- it will be inherited by grandchildren as well. This causes problems
- if a hook script puts long-running jobs in the background. Even if
- they redirect stderr to something else, the write end of our pipe will
- still be open, causing us to block. */
- apr_err = apr_file_inherit_unset(read_errhandle);
- if (apr_err)
- return svn_error_wrap_apr
- (apr_err, _("Can't make pipe read handle non-inherited for hook '%s'"),
- cmd);
-
- apr_err = apr_file_inherit_unset(write_errhandle);
- if (apr_err)
- return svn_error_wrap_apr
- (apr_err, _("Can't make pipe write handle non-inherited for hook '%s'"),
- cmd);
-
if (result)
{
- /* Create a pipe to access stdout of the child. */
- apr_err = apr_file_pipe_create(&read_outhandle, &write_outhandle, pool);
- if (apr_err)
- return svn_error_wrap_apr
- (apr_err, _("Can't create pipe for hook '%s'"), cmd);
-
- apr_err = apr_file_inherit_unset(read_outhandle);
- if (apr_err)
- return svn_error_wrap_apr
- (apr_err,
- _("Can't make pipe read handle non-inherited for hook '%s'"), cmd);
-
- apr_err = apr_file_inherit_unset(write_outhandle);
- if (apr_err)
- return svn_error_wrap_apr
- (apr_err,
- _("Can't make pipe write handle non-inherited for hook '%s'"), cmd);
+ null_handle = NULL;
}
else
{
@@ -238,26 +196,9 @@ run_hook_cmd(svn_string_t **result,
(apr_err, _("Can't create null stdout for hook '%s'"), cmd);
}
- err = svn_io_start_cmd(&cmd_proc, ".", cmd, args, FALSE,
- stdin_handle, result ? write_outhandle : null_handle,
- write_errhandle, pool);
-
- /* This seems to be done automatically if we pass the third parameter of
- apr_procattr_child_in/out_set(), but svn_io_run_cmd()'s interface does
- not support those parameters. We need to close the write end of the
- pipe so we don't hang on the read end later, if we need to read it. */
- apr_err = apr_file_close(write_errhandle);
- if (!err && apr_err)
- return svn_error_wrap_apr
- (apr_err, _("Error closing write end of stderr pipe"));
-
- if (result)
- {
- apr_err = apr_file_close(write_outhandle);
- if (!err && apr_err)
- return svn_error_wrap_apr
- (apr_err, _("Error closing write end of stderr pipe"));
- }
+ err = svn_io_start_cmd2(&cmd_proc, ".", cmd, args, FALSE,
+ FALSE, stdin_handle, result != NULL, null_handle,
+ TRUE, NULL, pool);
if (err)
{
@@ -266,13 +207,13 @@ run_hook_cmd(svn_string_t **result,
}
else
{
- err = check_hook_result(name, cmd, &cmd_proc, read_errhandle, pool);
+ err = check_hook_result(name, cmd, &cmd_proc, cmd_proc.err, pool);
}
/* Hooks are fallible, and so hook failure is "expected" to occur at
times. When such a failure happens we still want to close the pipe
and null file */
- apr_err = apr_file_close(read_errhandle);
+ apr_err = apr_file_close(cmd_proc.err);
if (!err && apr_err)
return svn_error_wrap_apr
(apr_err, _("Error closing read end of stderr pipe"));
@@ -280,8 +221,8 @@ run_hook_cmd(svn_string_t **result,
if (result)
{
svn_stringbuf_t *native_stdout;
- SVN_ERR(svn_stringbuf_from_aprfile(&native_stdout, read_outhandle, pool));
- apr_err = apr_file_close(read_outhandle);
+ SVN_ERR(svn_stringbuf_from_aprfile(&native_stdout, cmd_proc.out, pool));
+ apr_err = apr_file_close(cmd_proc.out);
if (!err && apr_err)
return svn_error_wrap_apr
(apr_err, _("Error closing read end of stderr pipe"));
Modified: subversion/branches/performance/subversion/libsvn_repos/load-fs-vtable.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_repos/load-fs-vtable.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_repos/load-fs-vtable.c (original)
+++ subversion/branches/performance/subversion/libsvn_repos/load-fs-vtable.c Wed Dec 29 21:12:33 2010
@@ -52,6 +52,7 @@ struct parse_baton
svn_fs_t *fs;
svn_boolean_t use_history;
+ svn_boolean_t validate_props;
svn_boolean_t use_pre_commit_hook;
svn_boolean_t use_post_commit_hook;
enum svn_repos_load_uuid uuid_action;
@@ -111,6 +112,44 @@ struct node_baton
/*----------------------------------------------------------------------*/
+
+/* Change revision property NAME to VALUE for REVISION in REPOS. If
+ VALIDATE_PROPS is set, use functions which perform validation of
+ the property value. Otherwise, bypass those checks. */
+static svn_error_t *
+change_rev_prop(svn_repos_t *repos,
+ svn_revnum_t revision,
+ const char *name,
+ const svn_string_t *value,
+ svn_boolean_t validate_props,
+ apr_pool_t *pool)
+{
+ if (validate_props)
+ return svn_fs_change_rev_prop2(svn_repos_fs(repos), revision, name,
+ NULL, value, pool);
+ else
+ return svn_repos_fs_change_rev_prop4(repos, revision, NULL, name,
+ NULL, value, FALSE, FALSE,
+ NULL, NULL, pool);
+}
+
+/* Change property NAME to VALUE for PATH in TXN_ROOT. If
+ VALIDATE_PROPS is set, use functions which perform validation of
+ the property value. Otherwise, bypass those checks. */
+static svn_error_t *
+change_node_prop(svn_fs_root_t *txn_root,
+ const char *path,
+ const char *name,
+ const svn_string_t *value,
+ svn_boolean_t validate_props,
+ apr_pool_t *pool)
+{
+ if (validate_props)
+ return svn_repos_fs_change_node_prop(txn_root, path, name, value, pool);
+ else
+ return svn_fs_change_node_prop(txn_root, path, name, value, pool);
+}
+
/* Prepend the mergeinfo source paths in MERGEINFO_ORIG with PARENT_DIR, and
return it in *MERGEINFO_VAL. */
static svn_error_t *
@@ -279,8 +318,9 @@ renumber_mergeinfo_revs(svn_string_t **f
/** vtable for doing commits to a fs **/
-static struct node_baton *
-make_node_baton(apr_hash_t *headers,
+static svn_error_t *
+make_node_baton(struct node_baton **node_baton_p,
+ apr_hash_t *headers,
struct revision_baton *rb,
apr_pool_t *pool)
{
@@ -344,26 +384,29 @@ make_node_baton(apr_hash_t *headers,
if ((val = apr_hash_get(headers, SVN_REPOS_DUMPFILE_TEXT_CONTENT_CHECKSUM,
APR_HASH_KEY_STRING)))
{
- svn_checksum_parse_hex(&nb->result_checksum, svn_checksum_md5, val, pool);
+ SVN_ERR(svn_checksum_parse_hex(&nb->result_checksum, svn_checksum_md5,
+ val, pool));
}
if ((val = apr_hash_get(headers, SVN_REPOS_DUMPFILE_TEXT_DELTA_BASE_CHECKSUM,
APR_HASH_KEY_STRING)))
{
- svn_checksum_parse_hex(&nb->base_checksum, svn_checksum_md5, val, pool);
+ SVN_ERR(svn_checksum_parse_hex(&nb->base_checksum, svn_checksum_md5, val,
+ pool));
}
if ((val = apr_hash_get(headers, SVN_REPOS_DUMPFILE_TEXT_COPY_SOURCE_CHECKSUM,
APR_HASH_KEY_STRING)))
{
- svn_checksum_parse_hex(&nb->copy_source_checksum, svn_checksum_md5, val,
- pool);
+ SVN_ERR(svn_checksum_parse_hex(&nb->copy_source_checksum,
+ svn_checksum_md5, val, pool));
}
/* What's cool about this dump format is that the parser just
ignores any unrecognized headers. :-) */
- return nb;
+ *node_baton_p = nb;
+ return SVN_NO_ERROR;
}
static struct revision_baton *
@@ -539,7 +582,7 @@ new_node_record(void **node_baton,
_("Malformed dumpstream: "
"Revision 0 must not contain node records"));
- nb = make_node_baton(headers, rb, pool);
+ SVN_ERR(make_node_baton(&nb, headers, rb, pool));
/* Make sure we have an action we recognize. */
if (nb->action < svn_node_action_change
@@ -578,8 +621,7 @@ new_node_record(void **node_baton,
*node_baton = nb;
return SVN_NO_ERROR;
}
-
-
+
static svn_error_t *
set_revision_property(void *baton,
const char *name,
@@ -589,7 +631,10 @@ set_revision_property(void *baton,
if (rb->rev > 0)
{
- SVN_ERR(svn_fs_change_txn_prop(rb->txn, name, value, rb->pool));
+ if (rb->pb->validate_props)
+ SVN_ERR(svn_repos_fs_change_txn_prop(rb->txn, name, value, rb->pool));
+ else
+ SVN_ERR(svn_fs_change_txn_prop(rb->txn, name, value, rb->pool));
/* Remember any datestamp that passes through! (See comment in
close_revision() below.) */
@@ -606,8 +651,8 @@ set_revision_property(void *baton,
SVN_ERR(svn_fs_youngest_rev(&youngest_rev, pb->fs, rb->pool));
if (youngest_rev == 0)
- SVN_ERR(svn_fs_change_rev_prop2(pb->fs, 0, name, NULL, value,
- rb->pool));
+ SVN_ERR(change_rev_prop(pb->repos, 0, name, value,
+ pb->validate_props, rb->pool));
}
return SVN_NO_ERROR;
@@ -672,8 +717,8 @@ set_node_property(void *baton,
}
}
- return svn_fs_change_node_prop(rb->txn_root, nb->path,
- name, value, nb->pool);
+ return change_node_prop(rb->txn_root, nb->path, name, value,
+ pb->validate_props, nb->pool);
}
@@ -684,8 +729,8 @@ delete_node_property(void *baton,
struct node_baton *nb = baton;
struct revision_baton *rb = nb->rb;
- return svn_fs_change_node_prop(rb->txn_root, nb->path,
- name, NULL, nb->pool);
+ return change_node_prop(rb->txn_root, nb->path, name, NULL,
+ rb->pb->validate_props, nb->pool);
}
@@ -705,10 +750,8 @@ remove_node_props(void *baton)
const void *key;
apr_hash_this(hi, &key, NULL, NULL);
-
- SVN_ERR(svn_fs_change_node_prop(rb->txn_root, nb->path,
- (const char *) key, NULL,
- nb->pool));
+ SVN_ERR(change_node_prop(rb->txn_root, nb->path, key, NULL,
+ rb->pb->validate_props, nb->pool));
}
return SVN_NO_ERROR;
@@ -797,7 +840,18 @@ close_revision(void *baton)
}
/* Commit. */
- if ((err = svn_fs_commit_txn(&conflict_msg, new_rev, rb->txn, rb->pool)))
+ err = svn_fs_commit_txn(&conflict_msg, new_rev, rb->txn, rb->pool);
+ if (SVN_IS_VALID_REVNUM(*new_rev))
+ {
+ if (err)
+ {
+ /* ### Log any error, but better yet is to rev
+ ### close_revision()'s API to allow both new_rev and err
+ ### to be returned, see #3768. */
+ svn_error_clear(err);
+ }
+ }
+ else
{
svn_error_clear(svn_fs_abort_txn(rb->txn, rb->pool));
if (conflict_msg)
@@ -854,9 +908,8 @@ close_revision(void *baton)
Note that if rb->datestamp is NULL, that's fine -- if the dump
data doesn't carry a datestamp, we want to preserve that fact in
the load. */
- SVN_ERR(svn_fs_change_rev_prop(pb->fs, *new_rev,
- SVN_PROP_REVISION_DATE, rb->datestamp,
- rb->pool));
+ SVN_ERR(change_rev_prop(pb->repos, *new_rev, SVN_PROP_REVISION_DATE,
+ rb->datestamp, pb->validate_props, rb->pool));
if (pb->notify_func)
{
@@ -882,6 +935,7 @@ svn_repos_get_fs_build_parser3(const svn
void **parse_baton,
svn_repos_t *repos,
svn_boolean_t use_history,
+ svn_boolean_t validate_props,
enum svn_repos_load_uuid uuid_action,
const char *parent_dir,
svn_repos_notify_func_t notify_func,
@@ -906,6 +960,7 @@ svn_repos_get_fs_build_parser3(const svn
pb->repos = repos;
pb->fs = svn_repos_fs(repos);
pb->use_history = use_history;
+ pb->validate_props = validate_props;
pb->notify_func = notify_func;
pb->notify_baton = notify_baton;
pb->notify = svn_repos_notify_create(svn_repos_notify_load_txn_start, pool);
@@ -930,6 +985,7 @@ svn_repos_load_fs3(svn_repos_t *repos,
const char *parent_dir,
svn_boolean_t use_pre_commit_hook,
svn_boolean_t use_post_commit_hook,
+ svn_boolean_t validate_props,
svn_repos_notify_func_t notify_func,
void *notify_baton,
svn_cancel_func_t cancel_func,
@@ -945,6 +1001,7 @@ svn_repos_load_fs3(svn_repos_t *repos,
SVN_ERR(svn_repos_get_fs_build_parser3(&parser, &parse_baton,
repos,
TRUE, /* look for copyfrom revs */
+ validate_props,
uuid_action,
parent_dir,
notify_func,
Modified: subversion/branches/performance/subversion/libsvn_subr/cache-memcache.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/cache-memcache.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/cache-memcache.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/cache-memcache.c Wed Dec 29 21:12:33 2010
@@ -75,10 +75,11 @@ struct svn_memcache_t {
2 * APR_MD5_DIGESTSIZE)
-/* Returns a memcache key for the given key KEY for CACHE, allocated
+/* Set *MC_KEY to a memcache key for the given key KEY for CACHE, allocated
in POOL. */
-static const char *
-build_key(memcache_t *cache,
+static svn_error_t *
+build_key(const char **mc_key,
+ memcache_t *cache,
const void *raw_key,
apr_pool_t *pool)
{
@@ -111,7 +112,8 @@ build_key(memcache_t *cache,
if (long_key_len > MEMCACHED_KEY_UNHASHED_LEN)
{
svn_checksum_t *checksum;
- svn_checksum(&checksum, svn_checksum_md5, long_key, long_key_len, pool);
+ SVN_ERR(svn_checksum(&checksum, svn_checksum_md5, long_key, long_key_len,
+ pool));
long_key = apr_pstrcat(pool,
apr_pstrmemdup(pool, long_key,
@@ -120,7 +122,8 @@ build_key(memcache_t *cache,
(char *)NULL);
}
- return long_key;
+ *mc_key = long_key;
+ return SVN_NO_ERROR;
}
@@ -138,7 +141,7 @@ memcache_get(void **value_p,
apr_size_t data_len;
apr_pool_t *subpool = svn_pool_create(pool);
- mc_key = build_key(cache, key, subpool);
+ SVN_ERR(build_key(&mc_key, cache, key, subpool));
apr_err = apr_memcache_getp(cache->memcache,
pool,
@@ -184,10 +187,12 @@ memcache_set(void *cache_void,
memcache_t *cache = cache_void;
apr_pool_t *subpool = svn_pool_create(pool);
char *data;
- const char *mc_key = build_key(cache, key, subpool);
+ const char *mc_key;
apr_size_t data_len;
apr_status_t apr_err;
+ SVN_ERR(build_key(&mc_key, cache, key, subpool));
+
if (cache->serialize_func)
{
SVN_ERR((cache->serialize_func)(&data, &data_len, value, subpool));
Modified: subversion/branches/performance/subversion/libsvn_subr/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/deprecated.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/deprecated.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/deprecated.c Wed Dec 29 21:12:33 2010
@@ -250,6 +250,16 @@ svn_subst_stream_translated_to_normal_fo
}
svn_error_t *
+svn_subst_translate_string(svn_string_t **new_value,
+ const svn_string_t *value,
+ const char *encoding,
+ apr_pool_t *pool)
+{
+ return svn_subst_translate_string2(new_value, NULL, NULL, value,
+ encoding, pool, pool);
+}
+
+svn_error_t *
svn_subst_stream_detranslated(svn_stream_t **stream_p,
const char *src,
svn_subst_eol_style_t eol_style,
@@ -754,6 +764,22 @@ svn_io_get_dirents(apr_hash_t **dirents,
return svn_io_get_dirents2(dirents, path, pool);
}
+svn_error_t *
+svn_io_start_cmd(apr_proc_t *cmd_proc,
+ const char *path,
+ const char *cmd,
+ const char *const *args,
+ svn_boolean_t inherit,
+ apr_file_t *infile,
+ apr_file_t *outfile,
+ apr_file_t *errfile,
+ apr_pool_t *pool)
+{
+ return svn_io_start_cmd2(cmd_proc, path, cmd, args, inherit, FALSE,
+ infile, FALSE, outfile, FALSE, errfile, pool);
+}
+
+
struct walk_func_filter_baton_t
{
svn_io_walk_func_t walk_func;
Modified: subversion/branches/performance/subversion/libsvn_subr/dirent_uri.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/dirent_uri.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/dirent_uri.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/dirent_uri.c Wed Dec 29 21:12:33 2010
@@ -2144,6 +2144,7 @@ svn_uri_condense_targets(const char **pc
/* Early exit when there's only one uri to work on. */
if (targets->nelts == 1)
{
+ *pcommon = apr_pstrdup(result_pool, *pcommon);
if (pcondensed_targets)
*pcondensed_targets = apr_array_make(result_pool, 0,
sizeof(const char *));
Modified: subversion/branches/performance/subversion/libsvn_subr/error.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/error.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/error.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/error.c Wed Dec 29 21:12:33 2010
@@ -34,34 +34,46 @@
#include "svn_utf.h"
#ifdef SVN_DEBUG
+/* XXX FIXME: These should be protected by a thread mutex.
+ svn_error__locate and make_error_internal should cooperate
+ in locking and unlocking it. */
+
+/* XXX TODO: Define mutex here #if APR_HAS_THREADS */
+static const char * volatile error_file = NULL;
+static long volatile error_line = -1;
+
/* file_line for the non-debug case. */
static const char SVN_FILE_LINE_UNDEFINED[] = "svn:<undefined>";
#endif /* SVN_DEBUG */
#include "svn_private_config.h"
+#include "private/svn_error_private.h"
-/*** Helpers for creating errors ***/
+/*
+ * Undefine the helpers for creating errors.
+ *
+ * *NOTE*: Any use of these functions in any other function may need
+ * to call svn_error__locate() because the macro that would otherwise
+ * do this is being undefined and the filename and line number will
+ * not be properly set in the static error_file and error_line
+ * variables.
+ */
#undef svn_error_create
#undef svn_error_createf
#undef svn_error_quick_wrap
#undef svn_error_wrap_apr
-
-/* XXX FIXME: These should be protected by a thread mutex.
- svn_error__locate and make_error_internal should cooperate
- in locking and unlocking it. */
-
-/* XXX TODO: Define mutex here #if APR_HAS_THREADS */
-static const char * volatile error_file = NULL;
-static long volatile error_line = -1;
-
+/* Note: This function was historically in the public API, so we need
+ * to define it even when !SVN_DEBUG. */
void
svn_error__locate(const char *file, long line)
{
+#if defined(SVN_DEBUG)
/* XXX TODO: Lock mutex here */
error_file = file;
error_line = line;
+#endif
}
@@ -103,11 +115,11 @@ make_error_internal(apr_status_t apr_err
new_error->apr_err = apr_err;
new_error->child = child;
new_error->pool = pool;
+#if defined(SVN_DEBUG)
new_error->file = error_file;
new_error->line = error_line;
/* XXX TODO: Unlock mutex here */
-#if defined(SVN_DEBUG)
if (! child)
apr_pool_cleanup_register(pool, new_error,
err_abort,
@@ -269,16 +281,16 @@ svn_error_root_cause(svn_error_t *err)
return err;
}
-svn_boolean_t
-svn_error_has_cause(svn_error_t *err, apr_status_t apr_err)
+svn_error_t *
+svn_error_find_cause(svn_error_t *err, apr_status_t apr_err)
{
svn_error_t *child;
for (child = err; child; child = child->child)
if (child->apr_err == apr_err)
- return TRUE;
+ return child;
- return FALSE;
+ return SVN_NO_ERROR;
}
svn_error_t *
@@ -331,8 +343,8 @@ svn_error_clear(svn_error_t *err)
}
}
-/* Is ERR a tracing-only error chain link? */
-static svn_boolean_t is_tracing_link(svn_error_t *err)
+svn_boolean_t
+svn_error__is_tracing_link(svn_error_t *err)
{
#ifdef SVN_ERR__TRACING
/* ### A strcmp()? Really? I think it's the best we can do unless
@@ -349,39 +361,46 @@ svn_error_t *
svn_error_purge_tracing(svn_error_t *err)
{
#ifdef SVN_ERR__TRACING
- svn_error_t *tmp_err = err;
svn_error_t *new_err = NULL, *new_err_leaf = NULL;
if (! err)
return SVN_NO_ERROR;
- while (tmp_err)
+ do
{
+ svn_error_t *tmp_err;
+
/* Skip over any trace-only links. */
- while (tmp_err && is_tracing_link(tmp_err))
- tmp_err = tmp_err->child;
+ while (err && svn_error__is_tracing_link(err))
+ err = err->child;
+
+ /* The link must be a real link in the error chain, otherwise an
+ error chain with trace only links would map into SVN_NO_ERROR. */
+ SVN_ERR_ASSERT(err);
+
+ /* Copy the current error except for its child error pointer
+ into the new error. Share any message and source filename
+ strings from the error. */
+ tmp_err = apr_palloc(err->pool, sizeof(*tmp_err));
+ *tmp_err = *err;
+ tmp_err->child = NULL;
/* Add a new link to the new chain (creating the chain if necessary). */
if (! new_err)
{
new_err = tmp_err;
- new_err_leaf = new_err;
+ new_err_leaf = tmp_err;
}
else
{
new_err_leaf->child = tmp_err;
- new_err_leaf = new_err_leaf->child;
+ new_err_leaf = tmp_err;
}
/* Advance to the next link in the original chain. */
- tmp_err = tmp_err->child;
- }
+ err = err->child;
+ } while (err);
- /* If we get here, there had better be a real link in this error chain. */
- SVN_ERR_ASSERT(new_err_leaf);
-
- /* Tie off the chain, and return its head. */
- new_err_leaf->child = NULL;
return new_err;
#else /* SVN_ERR__TRACING */
return err;
@@ -420,7 +439,7 @@ print_error(svn_error_t *err, FILE *stre
#endif /* SVN_DEBUG */
/* "traced call" */
- if (is_tracing_link(err))
+ if (svn_error__is_tracing_link(err))
{
/* Skip it. We already printed the file-line coordinates. */
}
@@ -550,7 +569,7 @@ const char *
svn_err_best_message(svn_error_t *err, char *buf, apr_size_t bufsize)
{
/* Skip over any trace records. */
- while (is_tracing_link(err))
+ while (svn_error__is_tracing_link(err))
err = err->child;
if (err->message)
return err->message;
@@ -593,6 +612,11 @@ svn_error_raise_on_malfunction(svn_boole
if (!can_return)
abort(); /* Nothing else we can do as a library */
+ /* The filename and line number of the error source needs to be set
+ here because svn_error_createf() is not the macro defined in
+ svn_error.h but the real function. */
+ svn_error__locate(file, line);
+
if (expr)
return svn_error_createf(SVN_ERR_ASSERTION_FAIL, NULL,
_("In file '%s' line %d: assertion failed (%s)"),
Modified: subversion/branches/performance/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/io.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/io.c Wed Dec 29 21:12:33 2010
@@ -756,7 +756,7 @@ svn_io_copy_file(const char *src,
#endif
SVN_ERR(svn_io_file_open(&from_file, src, APR_READ | APR_BINARY,
- APR_OS_DEFAULT, pool));
+ APR_OS_DEFAULT, pool));
/* For atomicity, we copy to a tmp file and then rename the tmp
file over the real destination. */
@@ -2189,15 +2189,18 @@ handle_child_process_error(apr_pool_t *p
svn_error_t *
-svn_io_start_cmd(apr_proc_t *cmd_proc,
- const char *path,
- const char *cmd,
- const char *const *args,
- svn_boolean_t inherit,
- apr_file_t *infile,
- apr_file_t *outfile,
- apr_file_t *errfile,
- apr_pool_t *pool)
+svn_io_start_cmd2(apr_proc_t *cmd_proc,
+ const char *path,
+ const char *cmd,
+ const char *const *args,
+ svn_boolean_t inherit,
+ svn_boolean_t infile_pipe,
+ apr_file_t *infile,
+ svn_boolean_t outfile_pipe,
+ apr_file_t *outfile,
+ svn_boolean_t errfile_pipe,
+ apr_file_t *errfile,
+ apr_pool_t *pool)
{
apr_status_t apr_err;
apr_procattr_t *cmdproc_attr;
@@ -2205,6 +2208,10 @@ svn_io_start_cmd(apr_proc_t *cmd_proc,
const char **args_native;
const char *cmd_apr;
+ SVN_ERR_ASSERT(!((infile != NULL) && infile_pipe));
+ SVN_ERR_ASSERT(!((outfile != NULL) && outfile_pipe));
+ SVN_ERR_ASSERT(!((errfile != NULL) && errfile_pipe));
+
/* Create the process attributes. */
apr_err = apr_procattr_create(&cmdproc_attr, pool);
if (apr_err)
@@ -2213,7 +2220,7 @@ svn_io_start_cmd(apr_proc_t *cmd_proc,
/* Make sure we invoke cmd directly, not through a shell. */
apr_err = apr_procattr_cmdtype_set(cmdproc_attr,
- inherit?APR_PROGRAM_PATH:APR_PROGRAM);
+ inherit ? APR_PROGRAM_PATH : APR_PROGRAM);
if (apr_err)
return svn_error_wrap_apr(apr_err, _("Can't set process '%s' cmdtype"),
cmd);
@@ -2257,6 +2264,13 @@ svn_io_start_cmd(apr_proc_t *cmd_proc,
(apr_err, _("Can't set process '%s' child errfile"), cmd);
}
+ /* Forward request for pipes to APR. */
+ if (infile_pipe || outfile_pipe || errfile_pipe)
+ apr_procattr_io_set(cmdproc_attr,
+ infile_pipe ? APR_FULL_BLOCK : APR_NO_PIPE,
+ outfile_pipe ? APR_FULL_BLOCK : APR_NO_PIPE,
+ errfile_pipe ? APR_FULL_BLOCK : APR_NO_PIPE);
+
/* Have the child print any problems executing its program to errfile. */
apr_err = apr_pool_userdata_set(errfile, ERRFILE_KEY, NULL, pool);
if (apr_err)
@@ -2348,8 +2362,9 @@ svn_io_run_cmd(const char *path,
{
apr_proc_t cmd_proc;
- SVN_ERR(svn_io_start_cmd(&cmd_proc, path, cmd, args, inherit,
- infile, outfile, errfile, pool));
+ SVN_ERR(svn_io_start_cmd2(&cmd_proc, path, cmd, args, inherit,
+ FALSE, infile, FALSE, outfile, FALSE, errfile,
+ pool));
return svn_io_wait_for_cmd(&cmd_proc, cmd, exitcode, exitwhy, pool);
}
Modified: subversion/branches/performance/subversion/libsvn_subr/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/mergeinfo.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/mergeinfo.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/mergeinfo.c Wed Dec 29 21:12:33 2010
@@ -668,7 +668,7 @@ parse_revision_line(const char **input,
absolute path key. */
existing_rangelist = apr_hash_get(hash, pathname->data, APR_HASH_KEY_STRING);
if (existing_rangelist)
- svn_rangelist_merge(&rangelist, existing_rangelist, pool);
+ SVN_ERR(svn_rangelist_merge(&rangelist, existing_rangelist, pool));
apr_hash_set(hash, pathname->data, APR_HASH_KEY_STRING, rangelist);
@@ -1188,9 +1188,9 @@ mergeinfo_hash_diff_cb(const void *key,
apr_array_header_t *deleted_rangelist, *added_rangelist;
from_rangelist = apr_hash_get(cb->from, path, APR_HASH_KEY_STRING);
to_rangelist = apr_hash_get(cb->to, path, APR_HASH_KEY_STRING);
- svn_rangelist_diff(&deleted_rangelist, &added_rangelist,
- from_rangelist, to_rangelist,
- cb->consider_inheritance, cb->pool);
+ SVN_ERR(svn_rangelist_diff(&deleted_rangelist, &added_rangelist,
+ from_rangelist, to_rangelist,
+ cb->consider_inheritance, cb->pool));
if (cb->deleted && deleted_rangelist->nelts > 0)
apr_hash_set(cb->deleted, apr_pstrdup(cb->pool, path),
APR_HASH_KEY_STRING, deleted_rangelist);
Modified: subversion/branches/performance/subversion/libsvn_subr/opt.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/opt.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/opt.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/opt.c Wed Dec 29 21:12:33 2010
@@ -662,7 +662,7 @@ svn_opt_push_implicit_dot_target(apr_arr
apr_pool_t *pool)
{
if (targets->nelts == 0)
- array_push_str(targets, "", pool); /* Ha! "", not ".", is the canonical */
+ APR_ARRAY_PUSH(targets, const char *) = ""; /* Ha! "", not ".", is the canonical */
assert(targets->nelts);
}