From 5a6f8694d942e107cf818c811735fb984a91693d Mon Sep 17 00:00:00 2001 From: Razvan Chitu Date: Mon, 8 Feb 2016 18:23:12 +0200 Subject: file-operations: replace io_scheduler in helper functions Nautilus file operations are implemented as asynchronous jobs scheduled using g_io_scheduler. Since g_io_scheduler has been deprecated, these operations should be using the simpler GTask API. In order to make this change possible, a first step would be to replace the scheduler in the helper functions called during the jobs. Replace g_io_scheduler_send_to_mainloop with g_main_context_invoke in helper functions. Since g_main_context_invoke is not blocking, add a mutex and a condition so the current thread is blocked until the operation is completed in the main loop. https://bugzilla.gnome.org/show_bug.cgi?id=761549 --- libnautilus-private/nautilus-file-operations.c | 70 ++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 9 deletions(-) diff --git a/libnautilus-private/nautilus-file-operations.c b/libnautilus-private/nautilus-file-operations.c index 9a93d8a70..87c185d52 100644 --- a/libnautilus-private/nautilus-file-operations.c +++ b/libnautilus-private/nautilus-file-operations.c @@ -1061,8 +1061,13 @@ typedef struct { const char *details_text; const char **button_titles; gboolean show_all; - int result; + /* Dialogs are ran from operation threads, which need to be blocked until + * the user gives a valid response + */ + gboolean completed; + GMutex mutex; + GCond cond; } RunSimpleDialogData; static gboolean @@ -1074,6 +1079,8 @@ do_run_simple_dialog (gpointer _data) int result; int response_id; + g_mutex_lock (&data->mutex); + /* Create the dialog. */ dialog = gtk_message_dialog_new (*data->parent_window, 0, @@ -1113,6 +1120,10 @@ do_run_simple_dialog (gpointer _data) gtk_widget_destroy (dialog); data->result = result; + data->completed = TRUE; + + g_cond_signal (&data->cond); + g_mutex_unlock (&data->mutex); return FALSE; } @@ -1145,6 +1156,9 @@ run_simple_dialog_va (CommonJob *job, data->secondary_text = secondary_text; data->details_text = details_text; data->show_all = show_all; + data->completed = FALSE; + g_mutex_init (&data->mutex); + g_cond_init (&data->cond); ptr_array = g_ptr_array_new (); while ((button_title = va_arg (varargs, const char *)) != NULL) { @@ -1154,13 +1168,24 @@ run_simple_dialog_va (CommonJob *job, data->button_titles = (const char **)g_ptr_array_free (ptr_array, FALSE); nautilus_progress_info_pause (job->progress); - g_io_scheduler_job_send_to_mainloop (job->io_job, - do_run_simple_dialog, - data, - NULL); + + g_mutex_lock (&data->mutex); + + g_main_context_invoke (NULL, + do_run_simple_dialog, + data); + + while (!data->completed) { + g_cond_wait (&data->cond, &data->mutex); + } + nautilus_progress_info_resume (job->progress); res = data->result; + g_mutex_unlock (&data->mutex); + g_mutex_clear (&data->mutex); + g_cond_clear (&data->cond); + g_free (data->button_titles); g_free (data); @@ -4374,6 +4399,12 @@ typedef struct { GFile *dest_dir; GtkWindow *parent; ConflictResponseData *resp_data; + /* Dialogs are ran from operation threads, which need to be blocked until + * the user gives a valid response + */ + gboolean completed; + GMutex mutex; + GCond cond; } ConflictDialogData; static gboolean @@ -4383,6 +4414,8 @@ do_run_conflict_dialog (gpointer _data) GtkWidget *dialog; int response; + g_mutex_lock (&data->mutex); + dialog = nautilus_file_conflict_dialog_new (data->parent, data->src, data->dest, @@ -4400,9 +4433,13 @@ do_run_conflict_dialog (gpointer _data) } data->resp_data->id = response; + data->completed = TRUE; gtk_widget_destroy (dialog); + g_cond_signal (&data->cond); + g_mutex_unlock (&data->mutex); + return FALSE; } @@ -4427,13 +4464,28 @@ run_conflict_dialog (CommonJob *job, resp_data->new_name = NULL; data->resp_data = resp_data; + data->completed = FALSE; + g_mutex_init (&data->mutex); + g_cond_init (&data->cond); + nautilus_progress_info_pause (job->progress); - g_io_scheduler_job_send_to_mainloop (job->io_job, - do_run_conflict_dialog, - data, - NULL); + + g_mutex_lock (&data->mutex); + + g_main_context_invoke (NULL, + do_run_conflict_dialog, + data); + + while (!data->completed) { + g_cond_wait (&data->cond, &data->mutex); + } + nautilus_progress_info_resume (job->progress); + g_mutex_unlock (&data->mutex); + g_mutex_clear (&data->mutex); + g_cond_clear (&data->cond); + g_slice_free (ConflictDialogData, data); g_timer_continue (job->time); -- cgit v1.2.1