[nautilus] file: get filesystem type asynchronously



commit bfd9ccf65c1b85dd6d38e17410debc23cb3c7daf
Author: Carlos Soriano <csoriano gnome org>
Date:   Wed Oct 14 12:14:50 2015 +0200

    file: get filesystem type asynchronously
    
    We were peeking the filesystem type synchronously since nautilus
    was checking for some file infos that are only required once
    synchronously. However the call for the filesystem is usually slow
    which makes nautilus main thread hang.
    
    To avoid I/O in the main thread, make the filesystem type request
    asynchronously and part of all the others attributes for the file.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=756280

 libnautilus-private/nautilus-directory-async.c |    9 ++++-
 libnautilus-private/nautilus-directory.c       |   48 +++-------------------
 libnautilus-private/nautilus-file-private.h    |    1 +
 libnautilus-private/nautilus-file.c            |   52 +++++++++++++++++++----
 libnautilus-private/nautilus-file.h            |    2 +
 5 files changed, 60 insertions(+), 52 deletions(-)
---
diff --git a/libnautilus-private/nautilus-directory-async.c b/libnautilus-private/nautilus-directory-async.c
index 0bb8c78..58b6d02 100644
--- a/libnautilus-private/nautilus-directory-async.c
+++ b/libnautilus-private/nautilus-directory-async.c
@@ -3951,6 +3951,7 @@ got_filesystem_info (FilesystemInfoState *state, GFileInfo *info)
 {
        NautilusDirectory *directory;
        NautilusFile *file;
+        char *filesystem_type;
 
        /* careful here, info may be NULL */
 
@@ -3967,6 +3968,11 @@ got_filesystem_info (FilesystemInfoState *state, GFileInfo *info)
                        g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_FILESYSTEM_USE_PREVIEW);
                file->details->filesystem_readonly = 
                        g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY);
+                filesystem_type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_FILESYSTEM_TYPE);
+                if (g_strcmp0 (eel_ref_str_peek (file->details->filesystem_type), filesystem_type) != 0) {
+                        eel_ref_str_unref (file->details->filesystem_type);
+                       file->details->filesystem_type = eel_ref_str_get_unique (filesystem_type);
+                }
        }
        
        nautilus_directory_async_state_changed (directory);
@@ -4038,7 +4044,8 @@ filesystem_info_start (NautilusDirectory *directory,
 
        g_file_query_filesystem_info_async (location,
                                            G_FILE_ATTRIBUTE_FILESYSTEM_READONLY ","
-                                           G_FILE_ATTRIBUTE_FILESYSTEM_USE_PREVIEW,
+                                           G_FILE_ATTRIBUTE_FILESYSTEM_USE_PREVIEW ","
+                                            G_FILE_ATTRIBUTE_FILESYSTEM_TYPE,
                                            G_PRIORITY_DEFAULT,
                                            state->cancellable, 
                                            query_filesystem_info_callback, 
diff --git a/libnautilus-private/nautilus-directory.c b/libnautilus-private/nautilus-directory.c
index 29a35f9..073e42c 100644
--- a/libnautilus-private/nautilus-directory.c
+++ b/libnautilus-private/nautilus-directory.c
@@ -601,55 +601,19 @@ nautilus_directory_is_in_recent (NautilusDirectory *directory)
        return g_file_has_uri_scheme (directory->details->location, "recent");
 }
 
-static const gchar * const remote_types[] = {
-  "afp",
-  "google-drive",
-  "sftp",
-  "webdav",
-  "ftp",
-  "nfs",
-  "cifs",
-  NULL
-};
-
 gboolean
 nautilus_directory_is_remote (NautilusDirectory *directory)
 {
-        GFileInfo *info;
+        NautilusFile *file;
         gboolean is_remote;
-        GError *error = NULL;
 
-       g_assert (NAUTILUS_IS_DIRECTORY (directory));
+        g_assert (NAUTILUS_IS_DIRECTORY (directory));
 
-       if (directory->details->location == NULL) {
-               return FALSE;
-       }
-
-       info = g_file_query_filesystem_info (directory->details->location, G_FILE_ATTRIBUTE_FILESYSTEM_TYPE,
-                                            NULL, &error);
-        if (error) {
-                /* Custom schemas like x-nautilus-desktop or other-locations:///
-                 * should not yell warnings */
-                if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
-                        g_warning ("Can't peek the uri: %s filesystem type with error: %s",
-                                   g_file_get_uri (directory->details->location), error->message);
-        }
-        g_clear_error (&error);
-        if (info) {
-                const gchar *type;
-
-                type = g_file_info_get_attribute_string (info, "filesystem::type");
-                if (type != NULL)
-                        is_remote = g_strv_contains (remote_types, type);
-                else
-                        is_remote = FALSE;
-
-                g_object_unref (info);
-        } else {
-                is_remote = FALSE;
-        }
+        file = nautilus_directory_get_corresponding_file (directory);
+        is_remote = nautilus_file_is_remote (file);
+        nautilus_file_unref (file);
 
-  return is_remote;
+        return is_remote;
 }
 
 gboolean
diff --git a/libnautilus-private/nautilus-file-private.h b/libnautilus-private/nautilus-file-private.h
index 97f6070..58eefbb 100644
--- a/libnautilus-private/nautilus-file-private.h
+++ b/libnautilus-private/nautilus-file-private.h
@@ -203,6 +203,7 @@ struct NautilusFileDetails
        eel_boolean_bit filesystem_readonly           : 1;
        eel_boolean_bit filesystem_use_preview        : 2; /* GFilesystemPreviewType */
        eel_boolean_bit filesystem_info_is_up_to_date : 1;
+        eel_ref_str     filesystem_type;
 
        time_t trash_time; /* 0 is unknown */
 
diff --git a/libnautilus-private/nautilus-file.c b/libnautilus-private/nautilus-file.c
index 57e2dd5..193edcb 100644
--- a/libnautilus-private/nautilus-file.c
+++ b/libnautilus-private/nautilus-file.c
@@ -837,6 +837,8 @@ finalize (GObject *object)
        }
 
        eel_ref_str_unref (file->details->filesystem_id);
+       eel_ref_str_unref (file->details->filesystem_type);
+        file->details->filesystem_type = NULL;
        g_free (file->details->trash_orig_path);
 
        g_list_free_full (file->details->mime_list, g_free);
@@ -4057,6 +4059,27 @@ nautilus_file_get_filesystem_use_preview (NautilusFile *file)
        return use_preview;
 }
 
+char *
+nautilus_file_get_filesystem_type (NautilusFile *file)
+{
+        NautilusFile *parent;
+        char *filesystem_type = NULL;
+
+        g_assert (NAUTILUS_IS_FILE (file));
+
+        if (nautilus_file_is_directory (file)) {
+                filesystem_type = g_strdup (eel_ref_str_peek (file->details->filesystem_type));
+        } else {
+                parent = nautilus_file_get_parent (file);
+                if (parent != NULL) {
+                        filesystem_type = g_strdup (eel_ref_str_peek (parent->details->filesystem_type));
+                        nautilus_file_unref (parent);
+                }
+        }
+
+        return filesystem_type;
+}
+
 gboolean
 nautilus_file_should_show_thumbnail (NautilusFile *file)
 {
@@ -7003,25 +7026,36 @@ nautilus_file_is_in_recent (NautilusFile *file)
        return nautilus_directory_is_in_recent (file->details->directory);
 }
 
+static const gchar * const remote_types[] = {
+  "afp",
+  "google-drive",
+  "sftp",
+  "webdav",
+  "ftp",
+  "nfs",
+  "cifs",
+  NULL
+};
+
 /**
  * nautilus_file_is_remote
- * 
- * Check if this file is a file in Network.
+ *
+ * Check if this file is a file in a remote filesystem.
  * @file: NautilusFile representing the file in question.
- * 
- * Returns: TRUE if @file is in Network.
+ *
+ * Returns: TRUE if @file is in a remote filesystem.
  * 
  **/
 gboolean
 nautilus_file_is_remote (NautilusFile *file)
 {
-       g_assert (NAUTILUS_IS_FILE (file));
+        char *filesystem_type;
+
+        g_assert (NAUTILUS_IS_FILE (file));
 
-        if (nautilus_file_is_directory (file))
-                return nautilus_directory_is_remote (nautilus_directory_get_for_file (file));
-        else
-               return nautilus_directory_is_remote (file->details->directory);
+        filesystem_type = nautilus_file_get_filesystem_type (file);
 
+        return filesystem_type != NULL && g_strv_contains (remote_types, filesystem_type);
 }
 
 /**
diff --git a/libnautilus-private/nautilus-file.h b/libnautilus-private/nautilus-file.h
index fb0f931..85a24d9 100644
--- a/libnautilus-private/nautilus-file.h
+++ b/libnautilus-private/nautilus-file.h
@@ -218,6 +218,8 @@ GFilesystemPreviewType  nautilus_file_get_filesystem_use_preview        (Nautilu
 
 char *                  nautilus_file_get_filesystem_id                 (NautilusFile                   
*file);
 
+char *                  nautilus_file_get_filesystem_type               (NautilusFile                   
*file);
+
 NautilusFile *          nautilus_file_get_trash_original_file           (NautilusFile                   
*file);
 
 /* Permissions. */


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