[evolution] Bug 650223 - evolution-backup does not terminate without --gui



commit 41337195f36e4795d7976df4e07a11ff336cd89c
Author: Matthew Barnes <mbarnes redhat com>
Date:   Mon May 16 16:53:03 2011 -0400

    Bug 650223 - evolution-backup does not terminate without --gui
    
    Use g_io_scheduler_push_job() instead of g_thread_create().  When the
    operation is finished, call gtk_main_quit() from the main thread using
    g_io_scheduler_job_send_to_mainloop().
    
    Also, check for cancellation with a GCancellable instead of a boolean.
    
    Note: We really should be using GLib's process spawning API
          instead of system(), but that's a job for another day.

 plugins/backup-restore/backup.c |  129 ++++++++++++++++++++++++--------------
 1 files changed, 81 insertions(+), 48 deletions(-)
---
diff --git a/plugins/backup-restore/backup.c b/plugins/backup-restore/backup.c
index aa79216..9b86230 100644
--- a/plugins/backup-restore/backup.c
+++ b/plugins/backup-restore/backup.c
@@ -72,7 +72,6 @@ static gint result = 0;
 static GtkWidget *progress_dialog;
 static GtkWidget *pbar;
 static gchar *txt = NULL;
-static gboolean complete = FALSE;
 
 static GOptionEntry options[] = {
 	{ "backup", '\0', 0, G_OPTION_ARG_NONE, &backup_op,
@@ -93,7 +92,6 @@ static GOptionEntry options[] = {
 #define d(x)
 
 #define print_and_run(x) G_STMT_START { g_message ("%s", x); system (x); } G_STMT_END
-#define CANCEL(x) if (x) return;
 
 static gboolean check (const gchar *filename, gboolean *is_new_format);
 
@@ -277,7 +275,8 @@ write_dir_file (void)
 }
 
 static void
-backup (const gchar *filename)
+backup (const gchar *filename,
+        GCancellable *cancellable)
 {
 	gchar *command;
 	gchar *quotedfname;
@@ -285,14 +284,18 @@ backup (const gchar *filename)
 	g_return_if_fail (filename && *filename);
 	quotedfname = g_shell_quote (filename);
 
-	CANCEL (complete);
+	if (g_cancellable_is_cancelled (cancellable))
+		return;
+
 	txt = _("Shutting down Evolution");
 	/* FIXME Will the versioned setting always work? */
 	run_cmd (EVOLUTION " --quit");
 
 	run_cmd ("rm $DATADIR/.running");
 
-	CANCEL (complete);
+	if (g_cancellable_is_cancelled (cancellable))
+		return;
+
 	txt = _("Backing Evolution accounts and settings");
 	run_cmd ("gconftool-2 --dump " GCONF_DIR " > " EVOLUTION_DIR GCONF_DUMP_FILE);
 
@@ -300,7 +303,9 @@ backup (const gchar *filename)
 
 	write_dir_file ();
 
-	CANCEL (complete);
+	if (g_cancellable_is_cancelled (cancellable))
+		return;
+
 	txt = _("Backing Evolution data (Mails, Contacts, Calendar, Tasks, Memos)");
 
 	/* FIXME stay on this file system ,other options?" */
@@ -318,10 +323,10 @@ backup (const gchar *filename)
 
 	if (restart_arg) {
 
-		CANCEL (complete);
-		txt = _("Restarting Evolution");
-		complete=TRUE;
+		if (g_cancellable_is_cancelled (cancellable))
+			return;
 
+		txt = _("Restarting Evolution");
 		run_cmd (EVOLUTION);
 	}
 
@@ -379,7 +384,8 @@ get_dir_level (const gchar *dir)
 }
 
 static void
-restore (const gchar *filename)
+restore (const gchar *filename,
+         GCancellable *cancellable)
 {
 	gchar *command;
 	gchar *quotedfname;
@@ -394,18 +400,24 @@ restore (const gchar *filename)
 
 	quotedfname = g_shell_quote (filename);
 
+	if (g_cancellable_is_cancelled (cancellable))
+		return;
+
 	/* FIXME Will the versioned setting always work? */
-	CANCEL (complete);
 	txt = _("Shutting down Evolution");
 	run_cmd (EVOLUTION " --quit");
 
-	CANCEL (complete);
+	if (g_cancellable_is_cancelled (cancellable))
+		return;
+
 	txt = _("Back up current Evolution data");
 	run_cmd ("mv $DATADIR $DATADIR_old");
 	run_cmd ("mv $CONFIGDIR $CONFIGDIR_old");
 	run_cmd ("mv $HOME/.camel_certs $HOME/.camel_certs_old");
 
-	CANCEL (complete);
+	if (g_cancellable_is_cancelled (cancellable))
+		return;
+
 	txt = _("Extracting files from back up");
 
 	if (is_new_format) {
@@ -462,7 +474,9 @@ restore (const gchar *filename)
 
 	g_free (quotedfname);
 
-	CANCEL (complete);
+	if (g_cancellable_is_cancelled (cancellable))
+		return;
+
 	txt = _("Loading Evolution settings");
 
 	if (is_new_format) {
@@ -477,7 +491,9 @@ restore (const gchar *filename)
 		run_cmd ("rm " "$HOME/.evolution/" GCONF_DUMP_FILE);
 	}
 
-	CANCEL (complete);
+	if (g_cancellable_is_cancelled (cancellable))
+		return;
+
 	txt = _("Removing temporary back up files");
 	run_cmd ("rm -rf $DATADIR_old");
 	run_cmd ("rm -rf $CONFIGDIR_old");
@@ -487,14 +503,17 @@ restore (const gchar *filename)
 	if (!is_new_format)
 		run_cmd ("rm -rf $HOME/.evolution_old");
 
-	CANCEL (complete);
+	if (g_cancellable_is_cancelled (cancellable))
+		return;
+
 	txt = _("Ensuring local sources");
 
  end:
 	if (restart_arg) {
-		CANCEL (complete);
+		if (g_cancellable_is_cancelled (cancellable))
+			return;
+
 		txt = _("Restarting Evolution");
-		complete=TRUE;
 		run_cmd (EVOLUTION);
 	}
 }
@@ -557,52 +576,48 @@ check (const gchar *filename, gboolean *is_new_format)
 }
 
 static gboolean
-pbar_update (gpointer data)
+pbar_update (GCancellable *cancellable)
 {
-	if (!complete) {
-		gtk_progress_bar_pulse ((GtkProgressBar *) pbar);
-		gtk_progress_bar_set_text ((GtkProgressBar *) pbar, txt);
-		return TRUE;
-	}
+	gtk_progress_bar_pulse ((GtkProgressBar *) pbar);
+	gtk_progress_bar_set_text ((GtkProgressBar *) pbar, txt);
 
-	gtk_main_quit ();
-	return FALSE;
+	/* Return TRUE to reschedule the timeout. */
+	return !g_cancellable_is_cancelled (cancellable);
 }
 
-static gpointer
-thread_start (gpointer data)
+static gboolean
+finish_job (gpointer user_data)
 {
-	if (backup_op)
-		backup (bk_file);
-	else if (restore_op)
-		restore (res_file);
-	else if (check_op)
-		check (chk_file, NULL);
-
-	complete = TRUE;
+	gtk_main_quit ();
 
-	return GINT_TO_POINTER (result);
+	return FALSE;
 }
 
 static gboolean
-idle_cb (gpointer data)
+start_job (GIOSchedulerJob *job,
+           GCancellable *cancellable,
+           gpointer user_data)
 {
-	if (gui_arg) {
-		/* Show progress dialog */
-		gtk_progress_bar_pulse ((GtkProgressBar *) pbar);
-		g_timeout_add (50, pbar_update, NULL);
-	}
+	if (backup_op)
+		backup (bk_file, cancellable);
+	else if (restore_op)
+		restore (res_file, cancellable);
+	else if (check_op)
+		check (chk_file, NULL);  /* not cancellable */
 
-	g_thread_create (thread_start, NULL, FALSE, NULL);
+	g_io_scheduler_job_send_to_mainloop_async (
+		job, finish_job, NULL, (GDestroyNotify) NULL);
 
 	return FALSE;
 }
 
 static void
-dlg_response (GtkWidget *dlg, gint response, gpointer data)
+dlg_response (GtkWidget *dlg,
+              gint response,
+              GCancellable *cancellable)
 {
 	/* We will cancel only backup/restore operations and not the check operation */
-	complete = TRUE;
+	g_cancellable_cancel (cancellable);
 
 	/* If the response is not of delete_event then destroy the event */
 	if (response != GTK_RESPONSE_NONE)
@@ -632,6 +647,7 @@ dlg_response (GtkWidget *dlg, gint response, gpointer data)
 gint
 main (gint argc, gchar **argv)
 {
+	GCancellable *cancellable;
 	gchar *file = NULL, *oper = NULL;
 	gint i;
 	GError *error = NULL;
@@ -691,6 +707,8 @@ main (gint argc, gchar **argv)
 		}
 	}
 
+	cancellable = g_cancellable_new ();
+
 	if (gui_arg && !check_op) {
 		GtkWidget *widget, *container;
 		GtkWidget *action_area;
@@ -789,7 +807,9 @@ main (gint argc, gchar **argv)
 			gtk_table_attach (GTK_TABLE (container), pbar, 1, 2, 2, 3, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
 
 		gtk_window_set_default_size ((GtkWindow *) progress_dialog, 450, 120);
-		g_signal_connect (progress_dialog, "response", G_CALLBACK(dlg_response), NULL);
+		g_signal_connect (
+			progress_dialog, "response",
+			G_CALLBACK (dlg_response), cancellable);
 		gtk_widget_show_all (progress_dialog);
 	} else if (check_op) {
 		/* For sanity we don't need gui */
@@ -797,8 +817,21 @@ main (gint argc, gchar **argv)
 		exit (result == 0 ? 0 : 1);
 	}
 
-	g_idle_add (idle_cb, NULL);
+	if (gui_arg)
+		g_timeout_add_full (
+			G_PRIORITY_DEFAULT, 50,
+			(GSourceFunc) pbar_update,
+			g_object_ref (cancellable),
+			(GDestroyNotify) g_object_unref);
+
+	g_io_scheduler_push_job (
+		start_job, NULL,
+		(GDestroyNotify) NULL,
+		G_PRIORITY_DEFAULT, cancellable);
+
 	gtk_main ();
 
+	g_object_unref (cancellable);
+
 	return result;
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]