subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hwri...@apache.org
Subject svn commit: r1238645 - in /subversion/trunk/subversion: libsvn_delta/compat.c libsvn_wc/update_editor.c
Date Tue, 31 Jan 2012 14:58:39 GMT
Author: hwright
Date: Tue Jan 31 14:58:38 2012
New Revision: 1238645

URL: http://svn.apache.org/viewvc?rev=1238645&view=rev
Log:
Ev2 shims: Introduce a proper callback for the unlocking of files, rather than
using a (technically no-op) deletion of a non-existant property.  Right now,
this all happens in the shims, so external code need not worry about it, but
eventually callers will need to provide this callback if they are interested
in such events.

* subversion/libsvn_wc/update_editor.c
  (fetch_props_func): Remove.
  (make_editor): Use the "standard" libsvn_wc fetch props func.
 
* subversion/libsvn_delta/compat.c
  (unlock_func_t): New.
  (ev2_edit_baton): Add new members.
  (action_code_t): Add new action.
  (process_actions): Handle the new action.
  (ev2_change_file_prop): Trap the special property, and translate it to a
    separate action.
  (delta_from_editor): Add new params and stash them in the baton.
  (do_unlock): New.
  (editor_from_delta): Add new output params, and set them appropriately.
  (svn_editor__insert_shims): Pass the unlock baton and func between shims.

Modified:
    subversion/trunk/subversion/libsvn_delta/compat.c
    subversion/trunk/subversion/libsvn_wc/update_editor.c

Modified: subversion/trunk/subversion/libsvn_delta/compat.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_delta/compat.c?rev=1238645&r1=1238644&r2=1238645&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_delta/compat.c (original)
+++ subversion/trunk/subversion/libsvn_delta/compat.c Tue Jan 31 14:58:38 2012
@@ -91,7 +91,18 @@ svn_compat_wrap_file_rev_handler(svn_fil
  * The general idea here is that we have to see *all* the actions on a node's
  * parent before we can process that node, which means we need to buffer a
  * large amount of information in the dir batons, and then process it in the
- * close_directory() handler. */
+ * close_directory() handler.
+ *
+ * There are a few ways we alter the callback stream.  One is when unlocking
+ * paths.  To tell a client a path should be unlocked, the server sends a
+ * prop-del for the SVN_PROP_ENTRY_LOCK_TOKEN property.  This causes problems,
+ * since the client doesn't have this property in the first place, but the
+ * deletion has side effects (unlike deleting a non-existent regular property
+ * would).  To solve this, we introduce *another* function into the API, not
+ * a part of the Ev2 callbacks, but a companion which is used to register
+ * the unlock of a path.  See ev2_change_file_prop() for implemenation
+ * details.
+ */
 
 typedef svn_error_t *(*start_edit_func_t)(
     void *baton,
@@ -102,6 +113,11 @@ typedef svn_error_t *(*target_revision_f
     svn_revnum_t target_revision,
     apr_pool_t *scratch_pool);
 
+typedef svn_error_t *(*unlock_func_t)(
+    void *baton,
+    const char *path,
+    apr_pool_t *scratch_pool);
+
 /* svn_editor__See insert_shims() for more information. */
 struct extra_baton
 {
@@ -125,6 +141,9 @@ struct ev2_edit_baton
 
   svn_delta_fetch_base_func_t fetch_base_func;
   void *fetch_base_baton;
+
+  unlock_func_t do_unlock;
+  void *unlock_baton;
 };
 
 struct ev2_dir_baton
@@ -155,7 +174,8 @@ enum action_code_t
   ACTION_ADD,
   ACTION_DELETE,
   ACTION_ADD_ABSENT,
-  ACTION_SET_TEXT
+  ACTION_SET_TEXT,
+  ACTION_UNLOCK
 };
 
 struct path_action
@@ -337,6 +357,12 @@ process_actions(void *edit_baton,
               break;
             }
 
+          case ACTION_UNLOCK:
+            {
+              SVN_ERR(eb->do_unlock(eb->unlock_baton, path, scratch_pool));
+              break;
+            }
+
           default:
             SVN_ERR_MALFUNCTION();
         }
@@ -754,6 +780,15 @@ ev2_change_file_prop(void *file_baton,
   struct ev2_file_baton *fb = file_baton;
   struct prop_args *p_args = apr_palloc(fb->eb->edit_pool, sizeof(*p_args));
 
+  if (!strcmp(name, SVN_PROP_ENTRY_LOCK_TOKEN) && value == NULL)
+    {
+      /* We special case the lock token propery deletion, which is the
+         server's way of telling the client to unlock the path. */
+      SVN_ERR(add_action(fb->eb, fb->path, ACTION_UNLOCK, NULL));
+    }
+
+  /* We also pass through the deletion, since there may actually exist such
+     a property we want to get rid of.   In the worse case, this is a no-op. */
   p_args->name = apr_pstrdup(fb->eb->edit_pool, name);
   p_args->value = value ? svn_string_dup(value, fb->eb->edit_pool) : NULL;
   p_args->base_revision = fb->base_revision;
@@ -809,6 +844,8 @@ static svn_error_t *
 delta_from_editor(const svn_delta_editor_t **deditor,
                   void **dedit_baton,
                   svn_editor_t *editor,
+                  unlock_func_t unlock_func,
+                  void *unlock_baton,
                   svn_boolean_t *found_abs_paths,
                   svn_delta_fetch_props_func_t fetch_props_func,
                   void *fetch_props_baton,
@@ -851,6 +888,9 @@ delta_from_editor(const svn_delta_editor
   eb->fetch_base_func = fetch_base_func;
   eb->fetch_base_baton = fetch_base_baton;
 
+  eb->do_unlock = unlock_func;
+  eb->unlock_baton = unlock_baton;
+
   *dedit_baton = eb;
   *deditor = &delta_editor;
 
@@ -1609,8 +1649,39 @@ target_revision_func(void *baton,
 }
 
 static svn_error_t *
+do_unlock(void *baton,
+          const char *path,
+          apr_pool_t *scratch_pool)
+{
+  struct editor_baton *eb = baton;
+  apr_array_header_t *path_bits = svn_path_decompose(path, scratch_pool);
+  const char *path_so_far = "";
+  struct operation *operation = &eb->root;
+  int i;
+
+  /* Look for any previous operations we've recognized for PATH.  If
+     any of PATH's ancestors have not yet been traversed, we'll be
+     creating OP_OPEN operations for them as we walk down PATH's path
+     components. */
+  for (i = 0; i < path_bits->nelts; ++i)
+    {
+      const char *path_bit = APR_ARRAY_IDX(path_bits, i, const char *);
+      path_so_far = svn_relpath_join(path_so_far, path_bit, scratch_pool);
+      operation = get_operation(path_so_far, operation, SVN_INVALID_REVNUM,
+                                eb->edit_pool);
+    }
+
+  APR_ARRAY_PUSH(operation->prop_dels, const char *) =
+                                                SVN_PROP_ENTRY_LOCK_TOKEN;
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
 editor_from_delta(svn_editor_t **editor_p,
                   struct extra_baton **exb,
+                  unlock_func_t *unlock_func,
+                  void **unlock_baton,
                   const svn_delta_editor_t *deditor,
                   void *dedit_baton,
                   svn_boolean_t *send_abs_paths,
@@ -1669,6 +1740,9 @@ editor_from_delta(svn_editor_t **editor_
 
   *editor_p = editor;
 
+  *unlock_func = do_unlock;
+  *unlock_baton = eb;
+
   extra_baton->start_edit = start_edit_func;
   extra_baton->target_revision = target_revision_func;
   extra_baton->baton = eb;
@@ -1721,7 +1795,11 @@ svn_editor__insert_shims(const svn_delta
   svn_boolean_t *found_abs_paths = apr_palloc(result_pool,
                                               sizeof(*found_abs_paths));
 
-  SVN_ERR(editor_from_delta(&editor, &exb, deditor_in, dedit_baton_in,
+  unlock_func_t unlock_func;
+  void *unlock_baton;
+
+  SVN_ERR(editor_from_delta(&editor, &exb, &unlock_func, &unlock_baton,
+                            deditor_in, dedit_baton_in,
                             found_abs_paths, NULL, NULL,
                             shim_callbacks->fetch_kind_func,
                             shim_callbacks->fetch_baton,
@@ -1729,6 +1807,7 @@ svn_editor__insert_shims(const svn_delta
                             shim_callbacks->fetch_baton,
                             result_pool, scratch_pool));
   SVN_ERR(delta_from_editor(deditor_out, dedit_baton_out, editor,
+                            unlock_func, unlock_baton,
                             found_abs_paths,
                             shim_callbacks->fetch_props_func,
                             shim_callbacks->fetch_baton,

Modified: subversion/trunk/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/update_editor.c?rev=1238645&r1=1238644&r2=1238645&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/update_editor.c Tue Jan 31 14:58:38 2012
@@ -4715,47 +4715,6 @@ close_edit(void *edit_baton,
   return SVN_NO_ERROR;
 }
 
-
-static svn_error_t *
-fetch_props_func(apr_hash_t **props,
-                 void *baton,
-                 const char *path,
-                 svn_revnum_t base_revision,
-                 apr_pool_t *result_pool,
-                 apr_pool_t *scratch_pool)
-{
-  struct svn_wc__shim_fetch_baton_t *sfb = baton;
-  const char *local_abspath = svn_dirent_join(sfb->base_abspath, path,
-                                              scratch_pool);
-  svn_error_t *err;
-
-  if (sfb->fetch_base)
-    err = svn_wc__db_base_get_props(props, sfb->db, local_abspath, result_pool,
-                                    scratch_pool);
-  else
-    err = svn_wc__db_read_props(props, sfb->db, local_abspath,
-                                result_pool, scratch_pool);
-
-  /* If the path doesn't exist, just return an empty set of props. */
-  if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
-    {
-      svn_error_clear(err);
-      *props = apr_hash_make(result_pool);
-    }
-  else if (err)
-    return svn_error_trace(err);
-
-  /* Add a bogus LOCK_TOKEN if we don't already have one, so as to catch
-     any deletions thereto. */
-  if (!apr_hash_get(*props, SVN_PROP_ENTRY_LOCK_TOKEN, APR_HASH_KEY_STRING))
-    {
-      apr_hash_set(*props, SVN_PROP_ENTRY_LOCK_TOKEN, APR_HASH_KEY_STRING,
-                   svn_string_create("This is completely bogus", result_pool));
-    }
-
-  return SVN_NO_ERROR;
-}
-
 
 /*** Returning editors. ***/
 
@@ -5032,7 +4991,7 @@ make_editor(svn_revnum_t *target_revisio
   sfb->fetch_base = TRUE;
 
   shim_callbacks->fetch_kind_func = svn_wc__fetch_kind_func;
-  shim_callbacks->fetch_props_func = fetch_props_func;
+  shim_callbacks->fetch_props_func = svn_wc__fetch_props_func;
   shim_callbacks->fetch_base_func = svn_wc__fetch_base_func;
   shim_callbacks->fetch_baton = sfb;
 



Mime
View raw message