aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2011-05-17 04:53:03 +0800
committerRodrigo Moya <rodrigo@gnome-db.org>2011-06-30 00:42:16 +0800
commit9640844be243e8639e1b2a2a74c6b441462fa032 (patch)
treedfde87eb982a4a84171bdaea913704743f85f062
parentb08569ecb2682ecea9e254c547dd45f86664ca43 (diff)
downloadgsoc2013-evolution-9640844be243e8639e1b2a2a74c6b441462fa032.tar.gz
gsoc2013-evolution-9640844be243e8639e1b2a2a74c6b441462fa032.tar.zst
gsoc2013-evolution-9640844be243e8639e1b2a2a74c6b441462fa032.zip
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.
-rw-r--r--plugins/backup-restore/backup.c129
1 files changed, 81 insertions, 48 deletions
diff --git a/plugins/backup-restore/backup.c b/plugins/backup-restore/backup.c
index aa792169f2..9b862309ee 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;
}