glib r6550 - trunk/gio



Author: alexl
Date: Thu Feb 21 12:35:05 2008
New Revision: 6550
URL: http://svn.gnome.org/viewvc/glib?rev=6550&view=rev

Log:
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.



Modified:
   trunk/gio/ChangeLog
   trunk/gio/gcontenttype.c
   trunk/gio/gfile.c
   trunk/gio/gfile.h
   trunk/gio/gfileinfo.h
   trunk/gio/gio.symbols
   trunk/gio/glocalfileinfo.c
   trunk/gio/gthemedicon.c
   trunk/gio/gthemedicon.h
   trunk/gio/gunionvolumemonitor.c
   trunk/gio/gvolumemonitor.c
   trunk/gio/gvolumemonitor.h

Modified: trunk/gio/gcontenttype.c
==============================================================================
--- trunk/gio/gcontenttype.c	(original)
+++ trunk/gio/gcontenttype.c	Thu Feb 21 12:35:05 2008
@@ -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_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 @@
 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);
 }
 
 /**

Modified: trunk/gio/gfile.c
==============================================================================
--- trunk/gio/gfile.c	(original)
+++ trunk/gio/gfile.c	Thu Feb 21 12:35:05 2008
@@ -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 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 @@
   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_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 @@
 
 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;

Modified: trunk/gio/gfile.h
==============================================================================
--- trunk/gio/gfile.h	(original)
+++ trunk/gio/gfile.h	Thu Feb 21 12:35:05 2008
@@ -198,8 +198,8 @@
  * @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 @@
 					     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 @@
 							   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);

Modified: trunk/gio/gfileinfo.h
==============================================================================
--- trunk/gio/gfileinfo.h	(original)
+++ trunk/gio/gfileinfo.h	Thu Feb 21 12:35:05 2008
@@ -80,6 +80,22 @@
   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 @@
 #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

Modified: trunk/gio/gio.symbols
==============================================================================
--- trunk/gio/gio.symbols	(original)
+++ trunk/gio/gio.symbols	Thu Feb 21 12:35:05 2008
@@ -253,6 +253,8 @@
 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_with_default_fallbacks
 g_themed_icon_new_from_names
 g_themed_icon_get_names
+g_themed_icon_append_name
 #endif
 #endif
 

Modified: trunk/gio/glocalfileinfo.c
==============================================================================
--- trunk/gio/glocalfileinfo.c	(original)
+++ trunk/gio/glocalfileinfo.c	Thu Feb 21 12:35:05 2008
@@ -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 @@
 	  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);

Modified: trunk/gio/gthemedicon.c
==============================================================================
--- trunk/gio/gthemedicon.c	(original)
+++ trunk/gio/gthemedicon.c	Thu Feb 21 12:35:05 2008
@@ -215,6 +215,28 @@
   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)
 {

Modified: trunk/gio/gthemedicon.h
==============================================================================
--- trunk/gio/gthemedicon.h	(original)
+++ trunk/gio/gthemedicon.h	Thu Feb 21 12:35:05 2008
@@ -51,6 +51,7 @@
 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);
 

Modified: trunk/gio/gunionvolumemonitor.c
==============================================================================
--- trunk/gio/gunionvolumemonitor.c	(original)
+++ trunk/gio/gunionvolumemonitor.c	Thu Feb 21 12:35:05 2008
@@ -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 @@
 #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 @@
   
   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 @@
 
   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 @@
       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 @@
 
   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 @@
       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 @@
 
   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 @@
       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 @@
 
   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 @@
 
     }
   
-  G_UNLOCK (the_volume_monitor);
+  g_static_rec_mutex_unlock (&the_volume_monitor_mutex);
 
   return volume;
 }
@@ -209,7 +211,7 @@
 
   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 @@
 
     }
   
-  G_UNLOCK (the_volume_monitor);
+  g_static_rec_mutex_unlock (&the_volume_monitor_mutex);
 
   return mount;
 }
@@ -470,6 +472,11 @@
 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 @@
 {
   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 @@
 
   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 @@
 
   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_UNLOCK (the_volume_monitor);*/
+  g_static_rec_mutex_unlock (&the_volume_monitor_mutex);
 
   return volume;
 }

Modified: trunk/gio/gvolumemonitor.c
==============================================================================
--- trunk/gio/gvolumemonitor.c	(original)
+++ trunk/gio/gvolumemonitor.c	Thu Feb 21 12:35:05 2008
@@ -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.

Modified: trunk/gio/gvolumemonitor.h
==============================================================================
--- trunk/gio/gvolumemonitor.h	(original)
+++ trunk/gio/gvolumemonitor.h	Thu Feb 21 12:35:05 2008
@@ -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.



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