You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2019/01/30 21:55:09 UTC

svn commit: r1852559 - in /subversion/trunk/subversion: include/private/svn_client_private.h libsvn_client/copy.c libsvn_client/shelf.c libsvn_client/wc_editor.c

Author: julianfoad
Date: Wed Jan 30 21:55:08 2019
New Revision: 1852559

URL: http://svn.apache.org/viewvc?rev=1852559&view=rev
Log:
Teach the WC editor to acquire and release a WC write lock.

* subversion/include/private/svn_client_private.h
  (svn_client__wc_editor): Document that it manages the write lock.
  (svn_client__wc_editor_internal): Add an option flag to manage the write lock.

* subversion/libsvn_client/copy.c
  (copy_foreign_dir,
   svn_client__repos_to_wc_copy_by_editor): Ask the WC editor not to manage
    the write lock for us here, as the caller does it.

* subversion/libsvn_client/shelf.c
  (svn_client__shelf_apply): Don't aquire and release the write lock here:
    let the WC editor do it.

* subversion/libsvn_client/wc_editor.c
  (edit_baton_t): Add fields to manage the write lock.
  (release_write_lock,
   pool_cleanup_handler): New.
  (edit_open): If requested, acquire the write lock and arrange for it to be
    released on pool clean-up.
  (edit_close): If acquired, release the write lock.
  (svn_client__wc_editor_internal): Add the option flag to manage the write
    lock. Initialize the 'abort_edit' method so that it will release the
    write lock, the same as 'close_edit'.
  (svn_client__wc_editor): Ask for the write lock to be managed.

Modified:
    subversion/trunk/subversion/include/private/svn_client_private.h
    subversion/trunk/subversion/libsvn_client/copy.c
    subversion/trunk/subversion/libsvn_client/shelf.c
    subversion/trunk/subversion/libsvn_client/wc_editor.c

Modified: subversion/trunk/subversion/include/private/svn_client_private.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_client_private.h?rev=1852559&r1=1852558&r2=1852559&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_client_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_client_private.h Wed Jan 30 21:55:08 2019
@@ -447,6 +447,9 @@ svn_client__repos_to_wc_copy_by_editor(s
  * RA_SESSION is used to fetch the original content for copies.
  *
  * Ignore changes to non-regular property (entry-props, DAV/WC-props).
+ *
+ * Acquire the WC write lock in 'open_root' and release it in
+ * 'close_edit', in 'abort_edit', or when @a result_pool is cleared.
  */
 svn_error_t *
 svn_client__wc_editor(const svn_delta_editor_t **editor_p,
@@ -468,6 +471,10 @@ svn_client__wc_editor(const svn_delta_ed
  *
  * If @a ignore_mergeinfo_changes is true, ignore any incoming changes
  * to the 'svn:mergeinfo' property.
+ *
+ * If @a manage_wc_write_lock is true, acquire the WC write lock in
+ * 'open_root' and release it in 'close_edit', in 'abort_edit', or
+ * when @a result_pool is cleared.
  */
 svn_error_t *
 svn_client__wc_editor_internal(const svn_delta_editor_t **editor_p,
@@ -475,6 +482,7 @@ svn_client__wc_editor_internal(const svn
                                const char *dst_abspath,
                                svn_boolean_t root_dir_add,
                                svn_boolean_t ignore_mergeinfo_changes,
+                               svn_boolean_t manage_wc_write_lock,
                                svn_wc_notify_func2_t notify_func,
                                void *notify_baton,
                                svn_ra_session_t *ra_session,

Modified: subversion/trunk/subversion/libsvn_client/copy.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/copy.c?rev=1852559&r1=1852558&r2=1852559&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/copy.c (original)
+++ subversion/trunk/subversion/libsvn_client/copy.c Wed Jan 30 21:55:08 2019
@@ -2384,6 +2384,7 @@ copy_foreign_dir(svn_ra_session_t *ra_se
                                          dst_abspath,
                                          TRUE /*root_dir_add*/,
                                          TRUE /*ignore_mergeinfo_changes*/,
+                                         FALSE /*manage_wc_write_lock*/,
                                          notify_func, notify_baton,
                                          NULL /*ra_session*/,
                                          ctx, scratch_pool));
@@ -2652,11 +2653,15 @@ svn_client__repos_to_wc_copy_by_editor(s
 
   SVN_ERR(svn_ra_reparent(ra_session, src_anchor, scratch_pool));
 
-  SVN_ERR(svn_client__wc_editor(&editor, &eb,
-                                svn_dirent_dirname(dst_abspath, scratch_pool),
-                                ctx->notify_func2, ctx->notify_baton2,
-                                ra_session,
-                                ctx, scratch_pool));
+  SVN_ERR(svn_client__wc_editor_internal(
+            &editor, &eb,
+            svn_dirent_dirname(dst_abspath, scratch_pool),
+            FALSE /*root_dir_add*/,
+            FALSE /*ignore_mergeinfo_changes*/,
+            FALSE /*manage_wc_write_lock*/,
+            ctx->notify_func2, ctx->notify_baton2,
+            ra_session,
+            ctx, scratch_pool));
 
   SVN_ERR(editor->open_root(eb, SVN_INVALID_REVNUM, scratch_pool, &rb));
   if (kind == svn_node_dir)

Modified: subversion/trunk/subversion/libsvn_client/shelf.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/shelf.c?rev=1852559&r1=1852558&r2=1852559&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/shelf.c (original)
+++ subversion/trunk/subversion/libsvn_client/shelf.c Wed Jan 30 21:55:08 2019
@@ -1961,12 +1961,9 @@ svn_client__shelf_apply(svn_client__shel
                          shelf->wc_root_abspath,
                          shelf->ctx, scratch_pool));
 
-  SVN_WC__CALL_WITH_WRITE_LOCK(
-    svn_client__shelf_replay(shelf_version, "",
-                             editor, edit_baton,
-                             scratch_pool),
-    shelf->ctx->wc_ctx, shelf->wc_root_abspath,
-    FALSE /*lock_anchor*/, scratch_pool);
+  SVN_ERR(svn_client__shelf_replay(shelf_version, "",
+                                   editor, edit_baton,
+                                   scratch_pool));
 
   svn_io_sleep_for_timestamps(shelf->wc_root_abspath,
                               scratch_pool);

Modified: subversion/trunk/subversion/libsvn_client/wc_editor.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/wc_editor.c?rev=1852559&r1=1852558&r2=1852559&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/wc_editor.c (original)
+++ subversion/trunk/subversion/libsvn_client/wc_editor.c Wed Jan 30 21:55:08 2019
@@ -74,6 +74,8 @@
 struct edit_baton_t
 {
   const char *anchor_abspath;
+  svn_boolean_t manage_wc_write_lock;
+  const char *lock_root_abspath;  /* the path locked, when locked */
 
   /* True => 'open_root' method will act as 'add_directory' */
   svn_boolean_t root_dir_add;
@@ -163,6 +165,31 @@ dir_open_or_add(struct dir_baton_t **chi
   return SVN_NO_ERROR;
 }
 
+/*  */
+static svn_error_t *
+release_write_lock(struct edit_baton_t *eb,
+                   apr_pool_t *scratch_pool)
+{
+  if (eb->lock_root_abspath)
+    {
+      SVN_ERR(svn_wc__release_write_lock(
+                eb->ctx->wc_ctx, eb->lock_root_abspath, scratch_pool));
+      eb->lock_root_abspath = NULL;
+    }
+  return SVN_NO_ERROR;
+}
+
+/*  */
+static apr_status_t
+pool_cleanup_handler(void *root_baton)
+{
+  struct dir_baton_t *db = root_baton;
+  struct edit_baton_t *eb = db->eb;
+
+  svn_error_clear(release_write_lock(eb, db->pool));
+  return APR_SUCCESS;
+}
+
 /* svn_delta_editor_t function */
 static svn_error_t *
 edit_open(void *edit_baton,
@@ -175,6 +202,19 @@ edit_open(void *edit_baton,
 
   SVN_ERR(dir_open_or_add(&db, "", NULL, eb, result_pool));
 
+  /* Acquire a WC write lock */
+  if (eb->manage_wc_write_lock)
+    {
+      apr_pool_cleanup_register(db->pool, db,
+                                pool_cleanup_handler,
+                                apr_pool_cleanup_null);
+      SVN_ERR(svn_wc__acquire_write_lock(&eb->lock_root_abspath,
+                                         eb->ctx->wc_ctx,
+                                         eb->anchor_abspath,
+                                         FALSE /*lock_anchor*/,
+                                         db->pool, db->pool));
+    }
+
   if (eb->root_dir_add)
     {
       SVN_ERR(mkdir(db->local_abspath, eb, result_pool));
@@ -186,9 +226,10 @@ edit_open(void *edit_baton,
 
 /* svn_delta_editor_t function */
 static svn_error_t *
-edit_close(void *edit_baton,
-           apr_pool_t *scratch_pool)
+edit_close_or_abort(void *edit_baton,
+                    apr_pool_t *scratch_pool)
 {
+  SVN_ERR(release_write_lock(edit_baton, scratch_pool));
   return SVN_NO_ERROR;
 }
 
@@ -509,6 +550,7 @@ svn_client__wc_editor_internal(const svn
                                const char *dst_abspath,
                                svn_boolean_t root_dir_add,
                                svn_boolean_t ignore_mergeinfo_changes,
+                               svn_boolean_t manage_wc_write_lock,
                                svn_wc_notify_func2_t notify_func,
                                void *notify_baton,
                                svn_ra_session_t *ra_session,
@@ -519,6 +561,8 @@ svn_client__wc_editor_internal(const svn
   struct edit_baton_t *eb = apr_pcalloc(result_pool, sizeof(*eb));
 
   eb->anchor_abspath = apr_pstrdup(result_pool, dst_abspath);
+  eb->manage_wc_write_lock = manage_wc_write_lock;
+  eb->lock_root_abspath = NULL;
   eb->root_dir_add = root_dir_add;
   eb->ignore_mergeinfo_changes = ignore_mergeinfo_changes;
 
@@ -529,7 +573,8 @@ svn_client__wc_editor_internal(const svn
   eb->notify_baton  = notify_baton;
 
   editor->open_root = edit_open;
-  editor->close_edit = edit_close;
+  editor->close_edit = edit_close_or_abort;
+  editor->abort_edit = edit_close_or_abort;
 
   editor->delete_entry = delete_entry;
 
@@ -563,6 +608,7 @@ svn_client__wc_editor(const svn_delta_ed
                                          dst_abspath,
                                          FALSE /*root_dir_add*/,
                                          FALSE /*ignore_mergeinfo_changes*/,
+                                         TRUE /*manage_wc_write_lock*/,
                                          notify_func, notify_baton,
                                          ra_session,
                                          ctx, result_pool));