You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by cm...@apache.org on 2010/11/16 21:39:08 UTC

svn commit: r1035792 - in /subversion/trunk/subversion/svnrdump: dump_editor.c dump_editor.h load_editor.c load_editor.h svnrdump.c

Author: cmpilato
Date: Tue Nov 16 20:39:08 2010
New Revision: 1035792

URL: http://svn.apache.org/viewvc?rev=1035792&view=rev
Log:
Fix issue #3716 ("svnrdump does not support cancellation").  Add
a cancellation function and signal handlers, and then use 'em.

* subversion/svnrdump/load_editor.h,
* subversion/svnrdump/load_editor.c
  (drive_dumpstream_loader): Add 'cancel_func' and 'cancel_baton'
    parameters, passed to svn_repos_parse_dumpstream2().

* subversion/svnrdump/dump_editor.h,
* subversion/svnrdump/dump_editor.c
  (get_dump_editor): Add 'cancel_func' and 'cancel_baton' parameters,
    used to wrap the returned editor in a standard cancellation editor.

* subversion/svnrdump/svnrdump.c
  (cancelled): New global variable.
  (signal_handler, check_cancel): New helper functions, copied
    wholesale from the source of our other Subversion binaries.
  (open_connection): Set ctx->cancel_func to check_cancel().
  (replay_revisions): Update call to get_dump_editor(), passing
    check_cancel() as the cancellation callback function.
  (load_revisions): Update call to drive_dumpstream_loader(), passing
    check_cancel() as the cancellation callback function.
  (main): Add the standard block of signal handler registrations used
    in all our binaries.

Modified:
    subversion/trunk/subversion/svnrdump/dump_editor.c
    subversion/trunk/subversion/svnrdump/dump_editor.h
    subversion/trunk/subversion/svnrdump/load_editor.c
    subversion/trunk/subversion/svnrdump/load_editor.h
    subversion/trunk/subversion/svnrdump/svnrdump.c

Modified: subversion/trunk/subversion/svnrdump/dump_editor.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svnrdump/dump_editor.c?rev=1035792&r1=1035791&r2=1035792&view=diff
==============================================================================
--- subversion/trunk/subversion/svnrdump/dump_editor.c (original)
+++ subversion/trunk/subversion/svnrdump/dump_editor.c Tue Nov 16 20:39:08 2010
@@ -843,6 +843,8 @@ svn_error_t *
 get_dump_editor(const svn_delta_editor_t **editor,
                 void **edit_baton,
                 svn_stream_t *stream,
+                svn_cancel_func_t cancel_func,
+                void *cancel_baton,
                 apr_pool_t *pool)
 {
   struct dump_edit_baton *eb;
@@ -878,5 +880,7 @@ get_dump_editor(const svn_delta_editor_t
   *edit_baton = eb;
   *editor = de;
 
-  return SVN_NO_ERROR;
+  /* Wrap this editor in a cancellation editor. */
+  return svn_delta_get_cancellation_editor(cancel_func, cancel_baton,
+                                           de, eb, editor, edit_baton, pool);
 }

Modified: subversion/trunk/subversion/svnrdump/dump_editor.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svnrdump/dump_editor.h?rev=1035792&r1=1035791&r2=1035792&view=diff
==============================================================================
--- subversion/trunk/subversion/svnrdump/dump_editor.h (original)
+++ subversion/trunk/subversion/svnrdump/dump_editor.h Tue Nov 16 20:39:08 2010
@@ -68,12 +68,16 @@ struct handler_baton
 
 /**
  * Get a dump editor @a editor along with a @a edit_baton allocated in
- * @a pool. The editor will write output to @a stream.
+ * @a pool.  The editor will write output to @a stream.  Use @a
+ * cancel_func and @a cancel_baton to check for user cancellation of
+ * the operation (for timely-but-safe termination).
  */
 svn_error_t *
 get_dump_editor(const svn_delta_editor_t **editor,
                 void **edit_baton,
                 svn_stream_t *stream,
+                svn_cancel_func_t cancel_func,
+                void *cancel_baton,
                 apr_pool_t *pool);
 
 /**

Modified: subversion/trunk/subversion/svnrdump/load_editor.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svnrdump/load_editor.c?rev=1035792&r1=1035791&r2=1035792&view=diff
==============================================================================
--- subversion/trunk/subversion/svnrdump/load_editor.c (original)
+++ subversion/trunk/subversion/svnrdump/load_editor.c Tue Nov 16 20:39:08 2010
@@ -662,6 +662,8 @@ drive_dumpstream_loader(svn_stream_t *st
                         const svn_repos_parse_fns2_t *parser,
                         void *parse_baton,
                         svn_ra_session_t *session,
+                        svn_cancel_func_t cancel_func,
+                        void *cancel_baton,
                         apr_pool_t *pool)
 {
   struct parse_baton *pb = parse_baton;
@@ -676,7 +678,7 @@ drive_dumpstream_loader(svn_stream_t *st
   SVN_ERR(get_lock(&lock_string, session, pool));
   SVN_ERR(svn_ra_get_repos_root2(session, &(pb->root_url), pool));
   SVN_ERR(svn_repos_parse_dumpstream2(stream, parser, parse_baton,
-                                      NULL, NULL, pool));
+                                      cancel_func, cancel_baton, pool));
   err = svn_ra_change_rev_prop2(session, 0, SVNRDUMP_PROP_LOCK,
                                  be_atomic ? &lock_string : NULL, NULL, pool);
   if (is_atomicity_error(err))

Modified: subversion/trunk/subversion/svnrdump/load_editor.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svnrdump/load_editor.h?rev=1035792&r1=1035791&r2=1035792&view=diff
==============================================================================
--- subversion/trunk/subversion/svnrdump/load_editor.h (original)
+++ subversion/trunk/subversion/svnrdump/load_editor.h Tue Nov 16 20:39:08 2010
@@ -104,13 +104,17 @@ get_dumpstream_loader(const svn_repos_pa
  * Drive the dumpstream loader described by @a parser and @a
  * parse_baton to parse and commit the stream @a stream to the
  * location described by @a session. Use @a pool for all memory
- * allocations.
+ * allocations.  Use @a cancel_func and @a cancel_baton to check for
+ * user cancellation of the operation (for timely-but-safe
+ * termination).
  */
 svn_error_t *
 drive_dumpstream_loader(svn_stream_t *stream,
                         const svn_repos_parse_fns2_t *parser,
                         void *parse_baton,
                         svn_ra_session_t *session,
+                        svn_cancel_func_t cancel_func,
+                        void *cancel_baton,
                         apr_pool_t *pool);
 
 #endif

Modified: subversion/trunk/subversion/svnrdump/svnrdump.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svnrdump/svnrdump.c?rev=1035792&r1=1035791&r2=1035792&view=diff
==============================================================================
--- subversion/trunk/subversion/svnrdump/svnrdump.c (original)
+++ subversion/trunk/subversion/svnrdump/svnrdump.c Tue Nov 16 20:39:08 2010
@@ -22,6 +22,8 @@
  * ====================================================================
  */
 
+#include <apr_signal.h>
+
 #include "svn_pools.h"
 #include "svn_cmdline.h"
 #include "svn_client.h"
@@ -39,6 +41,34 @@
 
 #include "private/svn_cmdline_private.h"
 
+
+
+/*** Cancellation ***/
+
+/* A flag to see if we've been cancelled by the client or not. */
+static volatile sig_atomic_t cancelled = FALSE;
+
+/* A signal handler to support cancellation. */
+static void
+signal_handler(int signum)
+{
+  apr_signal(signum, SIG_IGN);
+  cancelled = TRUE;
+}
+
+/* Our cancellation callback. */
+static svn_error_t *
+check_cancel(void *baton)
+{
+  if (cancelled)
+    return svn_error_create(SVN_ERR_CANCELLED, NULL, _("Caught signal"));
+  else
+    return SVN_NO_ERROR;
+}
+
+
+
+
 static svn_opt_subcommand_t dump_cmd, load_cmd;
 
 enum svn_svnrdump__longopt_t
@@ -228,6 +258,9 @@ open_connection(svn_ra_session_t **sessi
   cfg_config = apr_hash_get(ctx->config, SVN_CONFIG_CATEGORY_CONFIG,
                             APR_HASH_KEY_STRING);
 
+  /* Set up our cancellation support. */
+  ctx->cancel_func = check_cancel;
+
   /* Default authentication providers for non-interactive use */
   SVN_ERR(svn_cmdline_create_auth_baton(&(ctx->auth_baton), non_interactive,
                                         username, password, config_dir,
@@ -260,7 +293,8 @@ replay_revisions(svn_ra_session_t *sessi
 
   SVN_ERR(svn_stream_for_stdout(&stdout_stream, pool));
 
-  SVN_ERR(get_dump_editor(&dump_editor, &dump_baton, stdout_stream, pool));
+  SVN_ERR(get_dump_editor(&dump_editor, &dump_baton, stdout_stream, 
+                          check_cancel, NULL, pool));
 
   replay_baton = apr_pcalloc(pool, sizeof(*replay_baton));
   replay_baton->editor = dump_editor;
@@ -342,7 +376,7 @@ load_revisions(svn_ra_session_t *session
 
   SVN_ERR(get_dumpstream_loader(&parser, &parse_baton, session, pool));
   SVN_ERR(drive_dumpstream_loader(stdin_stream, parser, parse_baton,
-                                  session, pool));
+                                  session, check_cancel, NULL, pool));
 
   svn_stream_close(stdin_stream);
 
@@ -478,6 +512,29 @@ main(int argc, const char **argv)
 
   os->interleave = TRUE; /* Options and arguments can be interleaved */
 
+  /* Set up our cancellation support. */
+  apr_signal(SIGINT, signal_handler);
+#ifdef SIGBREAK
+  /* SIGBREAK is a Win32 specific signal generated by ctrl-break. */
+  apr_signal(SIGBREAK, signal_handler);
+#endif
+#ifdef SIGHUP
+  apr_signal(SIGHUP, signal_handler);
+#endif
+#ifdef SIGTERM
+  apr_signal(SIGTERM, signal_handler);
+#endif
+#ifdef SIGPIPE
+  /* Disable SIGPIPE generation for the platforms that have it. */
+  apr_signal(SIGPIPE, SIG_IGN);
+#endif
+#ifdef SIGXFSZ
+  /* Disable SIGXFSZ generation for the platforms that have it, otherwise
+   * working with large files when compiled against an APR that doesn't have
+   * large file support will crash the program, which is uncool. */
+  apr_signal(SIGXFSZ, SIG_IGN);
+#endif
+
   while (1)
     {
       int opt;