From bfda430eff9778c8b2b01c7af8fda19e491c9a7d Mon Sep 17 00:00:00 2001 From: David Zeuthen Date: Thu, 21 Feb 2008 12:35:05 +0000 Subject: [PATCH] Implement this function by moving bits from glocalfileinfo.c 2008-02-21 David Zeuthen * glocalfileinfo.c: (_g_local_file_info_get): * gcontenttype.c: (g_content_type_get_icon): Implement this function by moving bits from glocalfileinfo.c (g_content_type_get_description): Unalias before getting description (#517687) * gfile.c: (g_file_class_init), (g_file_query_filesystem_info_async), (g_file_query_filesystem_info_finish), (query_filesystem_info_data_free), (query_filesystem_info_async_thread), (g_file_real_query_filesystem_info_async), (g_file_real_query_filesystem_info_finish): * gfile.h: Implement async version of g_file_query_filesystem_info() * gfileinfo.h: Add new attributes for filesystem::use-preview * gio.symbols: Update * gthemedicon.c: (g_themed_icon_append_name): * gthemedicon.h: Add new new convenience function. * gunionvolumemonitor.c: (g_union_volume_monitor_dispose), (get_mounts), (get_volumes), (get_connected_drives), (get_volume_for_uuid), (get_mount_for_uuid), (g_union_volume_monitor_init), (populate_union_monitor), (g_volume_monitor_get), (_g_mount_get_for_mount_path), (g_volume_monitor_adopt_orphan_mount): * gvolumemonitor.c: * gvolumemonitor.h: Use recursive locks so it's safe for volume monitor implementations to call into the main volume monitor. Also separate object initialization and volume monitor initialization such that non-native volume monitors can properly adopt their mounts away. svn path=/trunk/; revision=6550 --- gio/ChangeLog | 39 +++++++++++ gio/gcontenttype.c | 36 ++++++++++- gio/gfile.c | 162 ++++++++++++++++++++++++++++++++++++++++++++++ gio/gfile.h | 24 +++++-- gio/gfileinfo.h | 26 ++++++++ gio/gio.symbols | 3 + gio/glocalfileinfo.c | 65 +++++++------------ gio/gthemedicon.c | 22 +++++++ gio/gthemedicon.h | 1 + gio/gunionvolumemonitor.c | 48 ++++++++------ gio/gvolumemonitor.c | 2 + gio/gvolumemonitor.h | 2 + 12 files changed, 362 insertions(+), 68 deletions(-) diff --git a/gio/ChangeLog b/gio/ChangeLog index cc0922f..dcf4479 100644 --- a/gio/ChangeLog +++ b/gio/ChangeLog @@ -1,3 +1,42 @@ +2008-02-21 David Zeuthen + + * glocalfileinfo.c: (_g_local_file_info_get): + * gcontenttype.c: + (g_content_type_get_icon): Implement this function by + moving bits from glocalfileinfo.c + (g_content_type_get_description): Unalias before getting + description (#517687) + + * gfile.c: (g_file_class_init), + (g_file_query_filesystem_info_async), + (g_file_query_filesystem_info_finish), + (query_filesystem_info_data_free), + (query_filesystem_info_async_thread), + (g_file_real_query_filesystem_info_async), + (g_file_real_query_filesystem_info_finish): + * gfile.h: Implement async version of + g_file_query_filesystem_info() + + * gfileinfo.h: Add new attributes for filesystem::use-preview + + * gio.symbols: Update + + * gthemedicon.c: (g_themed_icon_append_name): + * gthemedicon.h: Add new new convenience function. + + * gunionvolumemonitor.c: (g_union_volume_monitor_dispose), + (get_mounts), (get_volumes), (get_connected_drives), + (get_volume_for_uuid), (get_mount_for_uuid), + (g_union_volume_monitor_init), (populate_union_monitor), + (g_volume_monitor_get), (_g_mount_get_for_mount_path), + (g_volume_monitor_adopt_orphan_mount): + * gvolumemonitor.c: + * gvolumemonitor.h: Use recursive locks so it's safe for volume + monitor implementations to call into the main volume monitor. Also + separate object initialization and volume monitor initialization + such that non-native volume monitors can properly adopt their + mounts away. + 2008-02-21 Alexander Larsson * gfile.c: diff --git a/gio/gcontenttype.c b/gio/gcontenttype.c index 2b0f9d0..bd63d65 100644 --- a/gio/gcontenttype.c +++ b/gio/gcontenttype.c @@ -1,3 +1,5 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + /* GIO - GLib Input, Output and Streaming Library * * Copyright (C) 2006-2007 Red Hat, Inc. @@ -25,6 +27,7 @@ #include #include #include "gcontenttypeprivate.h" +#include "gthemedicon.h" #include "glibintl.h" #include "gioalias.h" @@ -591,6 +594,8 @@ g_content_type_get_description (const char *type) g_return_val_if_fail (type != NULL, NULL); G_LOCK (gio_xdgmime); + type = xdg_mime_unalias_mime_type (type); + if (type_comment_cache == NULL) type_comment_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); @@ -639,10 +644,35 @@ g_content_type_get_mime_type (const char *type) GIcon * g_content_type_get_icon (const char *type) { + char *mimetype_icon, *generic_mimetype_icon, *p; + char *icon_names[2]; + GThemedIcon *themed_icon; + g_return_val_if_fail (type != NULL, NULL); - - /* TODO: Implement */ - return NULL; + + mimetype_icon = g_strdup (type); + + while ((p = strchr (mimetype_icon, '/')) != NULL) + *p = '-'; + + p = strchr (type, '/'); + if (p == NULL) + p = type + strlen (type); + + generic_mimetype_icon = g_malloc (p - type + strlen ("-x-generic") + 1); + memcpy (generic_mimetype_icon, type, p - type); + memcpy (generic_mimetype_icon + (p - type), "-x-generic", strlen ("-x-generic")); + generic_mimetype_icon[(p - type) + strlen ("-x-generic")] = 0; + + icon_names[0] = mimetype_icon; + icon_names[1] = generic_mimetype_icon; + + themed_icon = g_themed_icon_new_from_names (icon_names, 2); + + g_free (mimetype_icon); + g_free (generic_mimetype_icon); + + return G_ICON (themed_icon); } /** diff --git a/gio/gfile.c b/gio/gfile.c index 03704f6..e065f84 100644 --- a/gio/gfile.c +++ b/gio/gfile.c @@ -1,3 +1,5 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + /* GIO - GLib Input, Output and Streaming Library * * Copyright (C) 2006-2007 Red Hat, Inc. @@ -129,6 +131,15 @@ static void g_file_real_query_info_async (GFile static GFileInfo * g_file_real_query_info_finish (GFile *file, GAsyncResult *res, GError **error); +static void g_file_real_query_filesystem_info_async (GFile *file, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +static GFileInfo * g_file_real_query_filesystem_info_finish (GFile *file, + GAsyncResult *res, + GError **error); static void g_file_real_enumerate_children_async (GFile *file, const char *attributes, GFileQueryInfoFlags flags, @@ -264,6 +275,8 @@ g_file_class_init (gpointer g_class, iface->set_display_name_finish = g_file_real_set_display_name_finish; iface->query_info_async = g_file_real_query_info_async; iface->query_info_finish = g_file_real_query_info_finish; + iface->query_filesystem_info_async = g_file_real_query_filesystem_info_async; + iface->query_filesystem_info_finish = g_file_real_query_filesystem_info_finish; iface->set_attributes_async = g_file_real_set_attributes_async; iface->set_attributes_finish = g_file_real_set_attributes_finish; iface->read_async = g_file_real_read_async; @@ -1148,6 +1161,81 @@ g_file_query_filesystem_info (GFile *file, } /** + * g_file_query_filesystem_info_async: + * @file: input #GFile. + * @attributes: an attribute query string. + * @io_priority: the I/O priority + * of the request. + * @cancellable: optional #GCancellable object, %NULL to ignore. + * @callback: a #GAsyncReadyCallback to call when the request is satisfied + * @user_data: the data to pass to callback function + * + * Asynchronously gets the requested information about the filesystem + * that the specified @file is on. The result is a #GFileInfo object + * that contains key-value attributes (such as type or size for the + * file). + * + * For more details, see g_file_query_filesystem_info() which is the + * synchronous version of this call. + * + * When the operation is finished, @callback will be called. You can + * then call g_file_query_info_finish() to get the result of the + * operation. + **/ +void +g_file_query_filesystem_info_async (GFile *file, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GFileIface *iface; + + g_return_if_fail (G_IS_FILE (file)); + + iface = G_FILE_GET_IFACE (file); + (* iface->query_filesystem_info_async) (file, + attributes, + io_priority, + cancellable, + callback, + user_data); +} + +/** + * g_file_query_filesystem_info_finish: + * @file: input #GFile. + * @res: a #GAsyncResult. + * @error: a #GError. + * + * Finishes an asynchronous filesystem info query. See + * g_file_query_filesystem_info_async(). + * + * Returns: #GFileInfo for given @file or %NULL on error. + **/ +GFileInfo * +g_file_query_filesystem_info_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + GFileIface *iface; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL); + + if (G_IS_SIMPLE_ASYNC_RESULT (res)) + { + GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res); + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + } + + iface = G_FILE_GET_IFACE (file); + return (* iface->query_filesystem_info_finish) (file, res, error); +} + +/** * g_file_find_enclosing_mount: * @file: input #GFile. * @cancellable: optional #GCancellable object, %NULL to ignore. @@ -3762,6 +3850,80 @@ g_file_real_query_info_finish (GFile *file, typedef struct { char *attributes; + GFileInfo *info; +} QueryFilesystemInfoAsyncData; + +static void +query_filesystem_info_data_free (QueryFilesystemInfoAsyncData *data) +{ + if (data->info) + g_object_unref (data->info); + g_free (data->attributes); + g_free (data); +} + +static void +query_filesystem_info_async_thread (GSimpleAsyncResult *res, + GObject *object, + GCancellable *cancellable) +{ + GError *error = NULL; + QueryFilesystemInfoAsyncData *data; + GFileInfo *info; + + data = g_simple_async_result_get_op_res_gpointer (res); + + info = g_file_query_filesystem_info (G_FILE (object), data->attributes, cancellable, &error); + + if (info == NULL) + { + g_simple_async_result_set_from_error (res, error); + g_error_free (error); + } + else + data->info = info; +} + +static void +g_file_real_query_filesystem_info_async (GFile *file, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *res; + QueryFilesystemInfoAsyncData *data; + + data = g_new0 (QueryFilesystemInfoAsyncData, 1); + data->attributes = g_strdup (attributes); + + res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_query_filesystem_info_async); + g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)query_filesystem_info_data_free); + + g_simple_async_result_run_in_thread (res, query_filesystem_info_async_thread, io_priority, cancellable); + g_object_unref (res); +} + +static GFileInfo * +g_file_real_query_filesystem_info_finish (GFile *file, + GAsyncResult *res, + GError **error) +{ + GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res); + QueryFilesystemInfoAsyncData *data; + + g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_file_real_query_filesystem_info_async); + + data = g_simple_async_result_get_op_res_gpointer (simple); + if (data->info) + return g_object_ref (data->info); + + return NULL; +} + +typedef struct { + char *attributes; GFileQueryInfoFlags flags; GFileEnumerator *enumerator; } EnumerateChildrenAsyncData; diff --git a/gio/gfile.h b/gio/gfile.h index e9e56aa..44776e0 100644 --- a/gio/gfile.h +++ b/gio/gfile.h @@ -198,8 +198,8 @@ typedef gboolean (* GFileReadMoreCallback) (const char *file_contents, * @query_info_async: Asynchronously gets the #GFileInfo for a #GFile. * @query_info_finish: Finishes an asynchronous query info operation. * @query_filesystem_info: Gets a #GFileInfo for the file system #GFile is on. - * @_query_filesystem_info_async: Asynchronously gets a #GFileInfo for the file system #GFile is on. - * @_query_filesystem_info_finish: Finishes asynchronously getting the file system info. + * @query_filesystem_info_async: Asynchronously gets a #GFileInfo for the file system #GFile is on. + * @query_filesystem_info_finish: Finishes asynchronously getting the file system info. * @find_enclosing_mount: Gets a #GMount for the #GFile. * @find_enclosing_mount_async: Asynchronously gets the #GMount for a #GFile. * @find_enclosing_mount_finish: Finishes asynchronously getting the volume. @@ -324,8 +324,15 @@ struct _GFileIface const char *attributes, GCancellable *cancellable, GError **error); - void (*_query_filesystem_info_async) (void); - void (*_query_filesystem_info_finish) (void); + void (*query_filesystem_info_async) (GFile *file, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + GFileInfo * (*query_filesystem_info_finish) (GFile *file, + GAsyncResult *res, + GError **error); GMount * (*find_enclosing_mount)(GFile *file, GCancellable *cancellable, @@ -661,6 +668,15 @@ GFileInfo * g_file_query_filesystem_info (GFile const char *attributes, GCancellable *cancellable, GError **error); +void g_file_query_filesystem_info_async (GFile *file, + const char *attributes, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GFileInfo * g_file_query_filesystem_info_finish (GFile *file, + GAsyncResult *res, + GError **error); GMount * g_file_find_enclosing_mount (GFile *file, GCancellable *cancellable, GError **error); diff --git a/gio/gfileinfo.h b/gio/gfileinfo.h index 79ad61d..78212b1 100644 --- a/gio/gfileinfo.h +++ b/gio/gfileinfo.h @@ -80,6 +80,22 @@ typedef enum { G_FILE_TYPE_MOUNTABLE } GFileType; +/** + * GFilesystemPreviewType: + * @G_FILESYSTEM_PREVIEW_TYPE_IF_ALWAYS: Only preview files if user has explicitly requested it. + * @G_FILESYSTEM_PREVIEW_TYPE_IF_LOCAL: Preview files if user has requested preview of "local" files. + * @G_FILESYSTEM_PREVIEW_TYPE_NEVER: Never preview files. + * + * Indicates a hint from the file system whether files should be + * previewed in a file manager. Returned as the value of the key + * #G_FILE_ATTRIBUTE_FILESYSTEM_USE_PREVIEW. + **/ +typedef enum { + G_FILESYSTEM_PREVIEW_TYPE_IF_ALWAYS = 0, + G_FILESYSTEM_PREVIEW_TYPE_IF_LOCAL, + G_FILESYSTEM_PREVIEW_TYPE_NEVER +} GFilesystemPreviewType; + /* Common Attributes: */ /** * G_FILE_ATTRIBUTE_STANDARD_TYPE: @@ -680,6 +696,16 @@ typedef enum { #define G_FILE_ATTRIBUTE_FILESYSTEM_READONLY "filesystem::readonly" /* boolean */ /** + * G_FILE_ATTRIBUTE_FILESYSTEM_USE_PREVIEW: + * + * A key in the "filesystem" namespace for hinting a file manager + * application whether it should preview (e.g. thumbnail) files on the + * file system. The value for this key contain a + * #GFilesystemPreviewType. + **/ +#define G_FILE_ATTRIBUTE_FILESYSTEM_USE_PREVIEW "filesystem::use-preview" /* uint32 (GFilesystemPreviewType) */ + +/** * G_FILE_ATTRIBUTE_GVFS_BACKEND: * * A key in the "gvfs" namespace that gets the name of the current diff --git a/gio/gio.symbols b/gio/gio.symbols index 6e725a4..611abc1 100644 --- a/gio/gio.symbols +++ b/gio/gio.symbols @@ -253,6 +253,8 @@ g_file_query_info g_file_query_info_async g_file_query_info_finish g_file_query_filesystem_info +g_file_query_filesystem_info_async +g_file_query_filesystem_info_finish g_file_find_enclosing_mount g_file_find_enclosing_mount_async g_file_find_enclosing_mount_finish @@ -627,6 +629,7 @@ g_themed_icon_new g_themed_icon_new_with_default_fallbacks g_themed_icon_new_from_names g_themed_icon_get_names +g_themed_icon_append_name #endif #endif diff --git a/gio/glocalfileinfo.c b/gio/glocalfileinfo.c index fa453ef..9c4538c 100644 --- a/gio/glocalfileinfo.c +++ b/gio/glocalfileinfo.c @@ -1,3 +1,5 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + /* GIO - GLib Input, Output and Streaming Library * * Copyright (C) 2006-2007 Red Hat, Inc. @@ -1488,48 +1490,31 @@ _g_local_file_info_get (const char *basename, if (g_file_attribute_matcher_matches (attribute_matcher, G_FILE_ATTRIBUTE_STANDARD_ICON)) { - char *mimetype_icon, *generic_mimetype_icon, *type_icon, *p; - char *icon_names[3]; GIcon *icon; - int i; - mimetype_icon = g_strdup (content_type); - - while ((p = strchr (mimetype_icon, '/')) != NULL) - *p = '-'; - - p = strchr (content_type, '/'); - if (p == NULL) - p = content_type + strlen (content_type); - - generic_mimetype_icon = g_malloc (p - content_type + strlen ("-x-generic") + 1); - memcpy (generic_mimetype_icon, content_type, p - content_type); - memcpy (generic_mimetype_icon + (p - content_type), "-x-generic", strlen ("-x-generic")); - generic_mimetype_icon[(p - content_type) + strlen ("-x-generic")] = 0; - - /* TODO: Special case desktop dir? That could be expensive with xdg dirs... */ - if (strcmp (path, g_get_home_dir ()) == 0) - type_icon = "user-home"; - else if (S_ISDIR (statbuf.st_mode)) - type_icon = "folder"; - else if (statbuf.st_mode & S_IXUSR) - type_icon = "application-x-executable"; - else - type_icon = "text-x-generic"; - - i = 0; - icon_names[i++] = mimetype_icon; - icon_names[i++] = generic_mimetype_icon; - if (strcmp (generic_mimetype_icon, type_icon) != 0 && - strcmp (mimetype_icon, type_icon) != 0) - icon_names[i++] = type_icon; - - icon = g_themed_icon_new_from_names (icon_names, i); - g_file_info_set_icon (info, icon); - - g_object_unref (icon); - g_free (mimetype_icon); - g_free (generic_mimetype_icon); + icon = g_content_type_get_icon (content_type); + if (icon != NULL) + { + if (G_IS_THEMED_ICON (icon)) + { + const char *type_icon; + + /* TODO: Special case desktop dir? That could be expensive with xdg dirs... */ + if (strcmp (path, g_get_home_dir ()) == 0) + type_icon = "user-home"; + else if (S_ISDIR (statbuf.st_mode)) + type_icon = "folder"; + else if (statbuf.st_mode & S_IXUSR) + type_icon = "application-x-executable"; + else + type_icon = "text-x-generic"; + + g_themed_icon_append_name (G_THEMED_ICON (icon), type_icon); + } + + g_file_info_set_icon (info, icon); + g_object_unref (icon); + } } g_free (content_type); diff --git a/gio/gthemedicon.c b/gio/gthemedicon.c index a7dc92b..6a3a963 100644 --- a/gio/gthemedicon.c +++ b/gio/gthemedicon.c @@ -215,6 +215,28 @@ g_themed_icon_get_names (GThemedIcon *icon) return (const char * const *)icon->names; } +/** + * g_themed_icon_append_name: + * @icon: a #GThemedIcon + * @iconname: name of icon to append to list of icons from within @icon. + * + * Append a name to the list of icons from within @icon. + */ +void +g_themed_icon_append_name (GThemedIcon *icon, const char *iconname) +{ + guint num_names; + char **new_names; + + g_return_if_fail (G_IS_THEMED_ICON (icon)); + g_return_if_fail (iconname != NULL); + + num_names = g_strv_length (icon->names); + icon->names = g_realloc (icon->names, sizeof (char*) * (num_names + 2)); + icon->names[num_names] = g_strdup (iconname); + icon->names[num_names + 1] = NULL; +} + static guint g_themed_icon_hash (GIcon *icon) { diff --git a/gio/gthemedicon.h b/gio/gthemedicon.h index f649e2d..5fb8a6b 100644 --- a/gio/gthemedicon.h +++ b/gio/gthemedicon.h @@ -51,6 +51,7 @@ GType g_themed_icon_get_type (void) G_GNUC_CONST; GIcon *g_themed_icon_new (const char *iconname); GIcon *g_themed_icon_new_with_default_fallbacks (const char *iconname); GIcon *g_themed_icon_new_from_names (char **iconnames, int len); +void g_themed_icon_append_name (GThemedIcon *icon, const char *iconname); const char * const *g_themed_icon_get_names (GThemedIcon *icon); diff --git a/gio/gunionvolumemonitor.c b/gio/gunionvolumemonitor.c index 73acc83..77e8aa0 100644 --- a/gio/gunionvolumemonitor.c +++ b/gio/gunionvolumemonitor.c @@ -1,3 +1,5 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + /* GIO - GLib Input, Output and Streaming Library * * Copyright (C) 2006-2007 Red Hat, Inc. @@ -51,8 +53,8 @@ static void g_union_volume_monitor_remove_monitor (GUnionVolumeMonitor *union_mo #define g_union_volume_monitor_get_type _g_union_volume_monitor_get_type G_DEFINE_TYPE (GUnionVolumeMonitor, g_union_volume_monitor, G_TYPE_VOLUME_MONITOR); +static GStaticRecMutex the_volume_monitor_mutex = G_STATIC_REC_MUTEX_INIT; -G_LOCK_DEFINE_STATIC(the_volume_monitor); static GUnionVolumeMonitor *the_volume_monitor = NULL; static void @@ -82,9 +84,9 @@ g_union_volume_monitor_dispose (GObject *object) monitor = G_UNION_VOLUME_MONITOR (object); - G_LOCK (the_volume_monitor); + g_static_rec_mutex_lock (&the_volume_monitor_mutex); the_volume_monitor = NULL; - G_UNLOCK (the_volume_monitor); + g_static_rec_mutex_unlock (&the_volume_monitor_mutex); if (G_OBJECT_CLASS (g_union_volume_monitor_parent_class)->dispose) (*G_OBJECT_CLASS (g_union_volume_monitor_parent_class)->dispose) (object); @@ -102,7 +104,7 @@ get_mounts (GVolumeMonitor *volume_monitor) res = NULL; - G_LOCK (the_volume_monitor); + g_static_rec_mutex_lock (&the_volume_monitor_mutex); for (l = monitor->monitors; l != NULL; l = l->next) { @@ -111,7 +113,7 @@ get_mounts (GVolumeMonitor *volume_monitor) res = g_list_concat (res, g_volume_monitor_get_mounts (child_monitor)); } - G_UNLOCK (the_volume_monitor); + g_static_rec_mutex_unlock (&the_volume_monitor_mutex); return res; } @@ -128,7 +130,7 @@ get_volumes (GVolumeMonitor *volume_monitor) res = NULL; - G_LOCK (the_volume_monitor); + g_static_rec_mutex_lock (&the_volume_monitor_mutex); for (l = monitor->monitors; l != NULL; l = l->next) { @@ -137,7 +139,7 @@ get_volumes (GVolumeMonitor *volume_monitor) res = g_list_concat (res, g_volume_monitor_get_volumes (child_monitor)); } - G_UNLOCK (the_volume_monitor); + g_static_rec_mutex_unlock (&the_volume_monitor_mutex); return res; } @@ -154,7 +156,7 @@ get_connected_drives (GVolumeMonitor *volume_monitor) res = NULL; - G_LOCK (the_volume_monitor); + g_static_rec_mutex_lock (&the_volume_monitor_mutex); for (l = monitor->monitors; l != NULL; l = l->next) { @@ -163,7 +165,7 @@ get_connected_drives (GVolumeMonitor *volume_monitor) res = g_list_concat (res, g_volume_monitor_get_connected_drives (child_monitor)); } - G_UNLOCK (the_volume_monitor); + g_static_rec_mutex_unlock (&the_volume_monitor_mutex); return res; } @@ -180,7 +182,7 @@ get_volume_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid) volume = NULL; - G_LOCK (the_volume_monitor); + g_static_rec_mutex_lock (&the_volume_monitor_mutex); for (l = monitor->monitors; l != NULL; l = l->next) { @@ -192,7 +194,7 @@ get_volume_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid) } - G_UNLOCK (the_volume_monitor); + g_static_rec_mutex_unlock (&the_volume_monitor_mutex); return volume; } @@ -209,7 +211,7 @@ get_mount_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid) mount = NULL; - G_LOCK (the_volume_monitor); + g_static_rec_mutex_lock (&the_volume_monitor_mutex); for (l = monitor->monitors; l != NULL; l = l->next) { @@ -221,7 +223,7 @@ get_mount_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid) } - G_UNLOCK (the_volume_monitor); + g_static_rec_mutex_unlock (&the_volume_monitor_mutex); return mount; } @@ -470,6 +472,11 @@ get_native_class () static void g_union_volume_monitor_init (GUnionVolumeMonitor *union_monitor) { +} + +static void +populate_union_monitor (GUnionVolumeMonitor *union_monitor) +{ GVolumeMonitor *monitor; GNativeVolumeMonitorClass *native_class; GVolumeMonitorClass *klass; @@ -526,17 +533,18 @@ g_volume_monitor_get (void) { GVolumeMonitor *vm; - G_LOCK (the_volume_monitor); + g_static_rec_mutex_lock (&the_volume_monitor_mutex); if (the_volume_monitor) vm = G_VOLUME_MONITOR (g_object_ref (the_volume_monitor)); else { the_volume_monitor = g_union_volume_monitor_new (); + populate_union_monitor (the_volume_monitor); vm = G_VOLUME_MONITOR (the_volume_monitor); } - G_UNLOCK (the_volume_monitor); + g_static_rec_mutex_unlock (&the_volume_monitor_mutex); return vm; } @@ -563,9 +571,9 @@ _g_mount_get_for_mount_path (const char *mount_path, if (klass->get_mount_for_mount_path) { - G_LOCK (the_volume_monitor); + g_static_rec_mutex_lock (&the_volume_monitor_mutex); mount = klass->get_mount_for_mount_path (mount_path, cancellable); - G_UNLOCK (the_volume_monitor); + g_static_rec_mutex_unlock (&the_volume_monitor_mutex); } /* TODO: How do we know this succeeded? Keep in mind that the native @@ -632,9 +640,7 @@ g_volume_monitor_adopt_orphan_mount (GMount *mount) volume = NULL; - /* TODO: nasty locking issues because current VM's don't emit signals in idle */ - - /*G_LOCK (the_volume_monitor);*/ + g_static_rec_mutex_lock (&the_volume_monitor_mutex); for (l = the_volume_monitor->monitors; l != NULL; l = l->next) { @@ -649,7 +655,7 @@ g_volume_monitor_adopt_orphan_mount (GMount *mount) } } - /*G_UNLOCK (the_volume_monitor);*/ + g_static_rec_mutex_unlock (&the_volume_monitor_mutex); return volume; } diff --git a/gio/gvolumemonitor.c b/gio/gvolumemonitor.c index d17438b..eea8601 100644 --- a/gio/gvolumemonitor.c +++ b/gio/gvolumemonitor.c @@ -1,3 +1,5 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + /* GIO - GLib Input, Output and Streaming Library * * Copyright (C) 2006-2007 Red Hat, Inc. diff --git a/gio/gvolumemonitor.h b/gio/gvolumemonitor.h index 193aca5..9e4a47d 100644 --- a/gio/gvolumemonitor.h +++ b/gio/gvolumemonitor.h @@ -1,3 +1,5 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + /* GIO - GLib Input, Output and Streaming Library * * Copyright (C) 2006-2007 Red Hat, Inc. -- 2.7.4