[rhythmbox] track-transfer-batch: create parent directories asynchronously



commit 23b78c2a31c56b95cd727205fddefcd17f6bf6c2
Author: Jonathan Matthew <jonathan d14n org>
Date:   Sun Oct 2 12:53:20 2016 +1000

    track-transfer-batch: create parent directories asynchronously
    
    This is a fairly slow operation on android devices, so doing it without
    blocking the main loop helps a bit.

 backends/gstreamer/rb-encoder-gst.c |   26 -----------
 shell/rb-track-transfer-batch.c     |   79 ++++++++++++++++++++++++++++------
 2 files changed, 65 insertions(+), 40 deletions(-)
---
diff --git a/backends/gstreamer/rb-encoder-gst.c b/backends/gstreamer/rb-encoder-gst.c
index f7b0506..4bc4cc1 100644
--- a/backends/gstreamer/rb-encoder-gst.c
+++ b/backends/gstreamer/rb-encoder-gst.c
@@ -693,32 +693,6 @@ impl_encode (RBEncoder *bencoder,
        g_free (encoder->priv->dest_uri);
        encoder->priv->dest_uri = NULL;
 
-       if (rb_uri_create_parent_dirs (dest, &error) == FALSE) {
-
-               /* this might be an msdos filesystem in disguise */
-               if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME)) {
-                       freedest = rb_sanitize_uri_for_filesystem (dest, "msdos");
-                       dest = freedest;
-
-                       g_clear_error (&error);
-                       rb_uri_create_parent_dirs (dest, &error);
-               }
-
-               if (error != NULL) {
-                       GError *nerror;
-                       nerror = g_error_new_literal (RB_ENCODER_ERROR,
-                                                     RB_ENCODER_ERROR_FILE_ACCESS,
-                                                     error->message);          /* I guess */
-
-                       set_error (encoder, nerror);
-                       g_error_free (error);
-                       g_error_free (nerror);
-                       g_idle_add ((GSourceFunc) cancel_idle, g_object_ref (encoder));
-                       g_free (freedest);
-                       return;
-               }
-       }
-
        /* keep ourselves alive in case we get cancelled by a signal handler */
        g_object_ref (encoder);
 
diff --git a/shell/rb-track-transfer-batch.c b/shell/rb-track-transfer-batch.c
index 2e39d52..8c08d08 100644
--- a/shell/rb-track-transfer-batch.c
+++ b/shell/rb-track-transfer-batch.c
@@ -40,6 +40,7 @@
 #include "rb-util.h"
 #include "rb-gst-media-types.h"
 #include "rb-task-progress.h"
+#include "rb-file-helpers.h"
 
 enum
 {
@@ -109,6 +110,7 @@ struct _RBTrackTransferBatchPrivate
        RhythmDBEntry *current;
        double current_entry_fraction;
        char *current_dest_uri;
+       gboolean current_dest_uri_sanitized;
        double current_fraction;
        RBEncoder *current_encoder;
        GstEncodingProfile *current_profile;
@@ -608,6 +610,59 @@ start_encoding (RBTrackTransferBatch *batch, gboolean overwrite)
                           batch->priv->current_profile);
 }
 
+static void
+create_parent_dirs_task (GTask *task, gpointer source_object, gpointer task_data, GCancellable *cancellable)
+{
+       RBTrackTransferBatch *batch;
+       GError *error = NULL;
+
+       batch = RB_TRACK_TRANSFER_BATCH (source_object);
+       rb_debug ("creating parent dirs for %s", batch->priv->current_dest_uri);
+       if (rb_uri_create_parent_dirs (batch->priv->current_dest_uri, &error) == FALSE) {
+               g_task_return_error (task, error);
+       } else {
+               g_task_return_boolean (task, TRUE);
+       }
+       g_object_unref (task);
+}
+
+static void
+create_parent_dirs_cb (GObject *source_object, GAsyncResult *result, gpointer data)
+{
+       RBTrackTransferBatch *batch;
+       GError *error = NULL;
+
+       batch = RB_TRACK_TRANSFER_BATCH (source_object);
+       if (g_task_propagate_boolean (G_TASK (result), &error) == FALSE) {
+
+               if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME) &&
+                   (batch->priv->current_dest_uri_sanitized == FALSE)) {
+                       GTask *task;
+                       char *dest;
+
+                       g_clear_error (&error);
+                       dest = rb_sanitize_uri_for_filesystem (batch->priv->current_dest_uri, "msdos");
+                       g_free (batch->priv->current_dest_uri);
+                       batch->priv->current_dest_uri = dest;
+                       batch->priv->current_dest_uri_sanitized = TRUE;
+
+                       rb_debug ("retrying parent dir creation with sanitized uri: %s", dest);
+                       task = g_task_new (batch, NULL, create_parent_dirs_cb, NULL);
+                       g_task_run_in_thread (task, create_parent_dirs_task);
+               } else {
+                       rb_debug ("failed to create parent directories for %s", 
batch->priv->current_dest_uri);
+                       track_transfer_completed (batch, 0, NULL, FALSE, error);
+               }
+       } else {
+               rb_debug ("parent directories for %s created", batch->priv->current_dest_uri);
+               g_signal_emit (batch, signals[TRACK_STARTED], 0,
+                              batch->priv->current,
+                              batch->priv->current_dest_uri);
+               start_encoding (batch, FALSE);
+               g_object_notify (G_OBJECT (batch), "task-detail");
+       }
+}
+
 static gboolean
 start_next (RBTrackTransferBatch *batch)
 {
@@ -617,16 +672,8 @@ start_next (RBTrackTransferBatch *batch)
                return FALSE;
        }
 
-       if (batch->priv->entries == NULL) {
-               /* guess we must be done.. */
-               g_signal_emit (batch, signals[COMPLETE], 0);
-               g_object_notify (G_OBJECT (batch), "task-outcome");
-               return FALSE;
-       }
-
-       batch->priv->current_fraction = 0.0;
-
        rb_debug ("%d entries remain in the batch", g_list_length (batch->priv->entries));
+       batch->priv->current_fraction = 0.0;
 
        while ((batch->priv->entries != NULL) && (batch->priv->cancelled == FALSE)) {
                RhythmDBEntry *entry;
@@ -698,6 +745,7 @@ start_next (RBTrackTransferBatch *batch)
 
                g_free (batch->priv->current_dest_uri);
                batch->priv->current_dest_uri = NULL;
+               batch->priv->current_dest_uri_sanitized = FALSE;
                g_signal_emit (batch, signals[GET_DEST_URI], 0,
                               entry,
                               media_type,
@@ -721,11 +769,14 @@ start_next (RBTrackTransferBatch *batch)
        }
 
        if (batch->priv->current != NULL) {
-               g_signal_emit (batch, signals[TRACK_STARTED], 0,
-                              batch->priv->current,
-                              batch->priv->current_dest_uri);
-               start_encoding (batch, FALSE);
-               g_object_notify (G_OBJECT (batch), "task-detail");
+               GTask *task;
+
+               task = g_task_new (batch, NULL, create_parent_dirs_cb, NULL);
+               g_task_run_in_thread (task, create_parent_dirs_task);
+       } else {
+               g_signal_emit (batch, signals[COMPLETE], 0);
+               g_object_notify (G_OBJECT (batch), "task-outcome");
+               return FALSE;
        }
 
        return TRUE;


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