Implement this function by moving bits from glocalfileinfo.c
authorDavid Zeuthen <davidz@redhat.com>
Thu, 21 Feb 2008 12:35:05 +0000 (12:35 +0000)
committerAlexander Larsson <alexl@src.gnome.org>
Thu, 21 Feb 2008 12:35:05 +0000 (12:35 +0000)
2008-02-21  David Zeuthen  <davidz@redhat.com>

* 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

12 files changed:
gio/ChangeLog
gio/gcontenttype.c
gio/gfile.c
gio/gfile.h
gio/gfileinfo.h
gio/gio.symbols
gio/glocalfileinfo.c
gio/gthemedicon.c
gio/gthemedicon.h
gio/gunionvolumemonitor.c
gio/gvolumemonitor.c
gio/gvolumemonitor.h

index cc0922f..dcf4479 100644 (file)
@@ -1,3 +1,42 @@
+2008-02-21  David Zeuthen  <davidz@redhat.com>
+
+       * 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  <alexl@redhat.com>
 
         * gfile.c:
index 2b0f9d0..bd63d65 100644 (file)
@@ -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 <string.h>
 #include <stdio.h>
 #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);
 }
 
 /**
index 03704f6..e065f84 100644 (file)
@@ -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 <link linkend="io-priority">I/O priority</link> 
+ *     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;
index e9e56aa..44776e0 100644 (file)
@@ -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);
index 79ad61d..78212b1 100644 (file)
@@ -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
index 6e725a4..611abc1 100644 (file)
@@ -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
 
index fa453ef..9c4538c 100644 (file)
@@ -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);
index a7dc92b..6a3a963 100644 (file)
@@ -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)
 {
index f649e2d..5fb8a6b 100644 (file)
@@ -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);
 
index 73acc83..77e8aa0 100644 (file)
@@ -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;
 }
index d17438b..eea8601 100644 (file)
@@ -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.
index 193aca5..9e4a47d 100644 (file)
@@ -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.