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;