gvfs r1860 - in trunk: . monitor/hal



Author: gicmo
Date: Tue Aug  5 00:53:16 2008
New Revision: 1860
URL: http://svn.gnome.org/viewvc/gvfs?rev=1860&view=rev

Log:
Bug 545489 â Nautilus hangs when inserting a CD

Fix callback with lock held and various ref counting
issues.


Modified:
   trunk/ChangeLog
   trunk/monitor/hal/ghaldrive.c
   trunk/monitor/hal/ghalvolume.c

Modified: trunk/monitor/hal/ghaldrive.c
==============================================================================
--- trunk/monitor/hal/ghaldrive.c	(original)
+++ trunk/monitor/hal/ghaldrive.c	Tue Aug  5 00:53:16 2008
@@ -1,5 +1,5 @@
 /* GIO - GLib Input, Output and Streaming Library
- * 
+ *
  * Copyright (C) 2006-2007 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
@@ -623,6 +623,7 @@
     }
   g_simple_async_result_complete (simple);
   g_object_unref (simple);
+  g_object_unref (data->object);
   g_free (data);
 }
 
@@ -647,7 +648,7 @@
   data->callback = callback;
   data->user_data = user_data;
   data->cancellable = cancellable;
-  
+
   error = NULL;
   if (!g_spawn_async (NULL,         /* working dir */
                       argv,
@@ -659,19 +660,20 @@
                       &error))
     {
       GSimpleAsyncResult *simple;
-      
+
       simple = g_simple_async_result_new_from_error (data->object,
                                                      data->callback,
                                                      data->user_data,
                                                      error);
       g_simple_async_result_complete (simple);
       g_object_unref (simple);
+      g_object_unref (drive);
       g_error_free (error);
       g_free (data);
     }
   else
     g_child_watch_add (child_pid, spawn_cb, data);
-    
+
   g_free (argv[4]);
 }
 
@@ -717,10 +719,10 @@
       if (error->code != G_IO_ERROR_FAILED_HANDLED)
         {
           g_error_free (error);
-          error = g_error_new (G_IO_ERROR, G_IO_ERROR_BUSY, 
+          error = g_error_new (G_IO_ERROR, G_IO_ERROR_BUSY,
                                _("Failed to eject media; one or more volumes on the media are busy."));
         }
-      
+
       /* unmount failed; need to fail the whole eject operation */
       simple = g_simple_async_result_new_from_error (G_OBJECT (data->drive),
                                                      data->callback,
@@ -758,6 +760,8 @@
                             data->cancellable,
                             data->callback,
                             data->user_data);
+
+      g_object_unref (data->drive);
       g_free (data);
     }
   else
@@ -789,7 +793,7 @@
   /* first we need to go through all the volumes and unmount their assoicated mounts (if any) */
 
   data = g_new0 (UnmountMountsOp, 1);
-  data->drive = drive;
+  data->drive = g_object_ref (drive);
   data->cancellable = cancellable;
   data->callback = callback;
   data->user_data = user_data;
@@ -831,14 +835,14 @@
   PollOp *data = (PollOp *) user_data;
   GSimpleAsyncResult *simple;
   DBusMessage *reply;
-  
+
   reply = dbus_pending_call_steal_reply (pending_call);
-  
+
   if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR)
     {
       GError *error;
       DBusError dbus_error;
-      
+
       dbus_error_init (&dbus_error);
       dbus_set_error_from_message (&dbus_error, reply);
       error = g_error_new (G_IO_ERROR,
@@ -855,18 +859,19 @@
       goto out;
     }
 
-  /* TODO: parse reply and extract result? 
-   * (the result is whether the media availability state changed) 
+  /* TODO: parse reply and extract result?
+   * (the result is whether the media availability state changed)
    */
-  
+
   simple = g_simple_async_result_new (data->object,
                                       data->callback,
                                       data->user_data,
                                       NULL);
   g_simple_async_result_complete (simple);
   g_object_unref (simple);
-  
+
  out:
+  g_object_unref (data->object);
   dbus_message_unref (reply);
   dbus_pending_call_unref (pending_call);
 }
@@ -885,7 +890,7 @@
   PollOp *data;
 
   data = g_new0 (PollOp, 1);
-  data->object = G_OBJECT (drive);
+  data->object = g_object_ref (drive);
   data->callback = callback;
   data->user_data = user_data;
   data->cancellable = cancellable;
@@ -894,12 +899,12 @@
 
   G_LOCK (hal_drive);
   con = hal_pool_get_dbus_connection (hal_drive->pool);
-  msg = dbus_message_new_method_call ("org.freedesktop.Hal", 
+  msg = dbus_message_new_method_call ("org.freedesktop.Hal",
                                       hal_device_get_udi (hal_drive->device),
                                       "org.freedesktop.Hal.Device.Storage.Removable",
                                       "CheckForMedia");
   G_UNLOCK (hal_drive);
-  
+
   if (!dbus_connection_send_with_reply (con, msg, &pending_call, -1))
     {
       GError *error;
@@ -914,6 +919,7 @@
       g_simple_async_result_complete (simple);
       g_object_unref (simple);
       g_error_free (error);
+      g_object_unref (data->object);
       g_free (data);
     }
   else
@@ -921,7 +927,7 @@
                                   poll_for_media_cb,
                                   data,
                                   (DBusFreeFunction) g_free);
-  
+
   dbus_message_unref (msg);
 }
 

Modified: trunk/monitor/hal/ghalvolume.c
==============================================================================
--- trunk/monitor/hal/ghalvolume.c	(original)
+++ trunk/monitor/hal/ghalvolume.c	Tue Aug  5 00:53:16 2008
@@ -1,5 +1,5 @@
 /* GIO - GLib Input, Output and Streaming Library
- * 
+ *
  * Copyright (C) 2006-2007 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
@@ -798,14 +798,11 @@
                       &child_pid,
                       &error))
     {
-      GSimpleAsyncResult *simple;
-      simple = g_simple_async_result_new_from_error (data->object,
-                                                     data->callback,
-                                                     data->user_data,
-                                                     error);
+      g_simple_async_report_gerror_in_idle (data->object,
+                                            data->callback,
+                                            data->user_data,
+                                            error);
       g_object_unref (data->object);
-      g_simple_async_result_complete (simple);
-      g_object_unref (simple);
       g_error_free (error);
       g_free (data);
       return;
@@ -828,6 +825,7 @@
 {
   ForeignMountOp *data = user_data;
   data->callback (G_OBJECT (data->enclosing_volume), res, data->user_data);
+  g_object_unref (data->enclosing_volume);
   g_free (data);
 }
 
@@ -852,7 +850,7 @@
       ForeignMountOp *data;
 
       data = g_new0 (ForeignMountOp, 1);
-      data->enclosing_volume = hal_volume;
+      data->enclosing_volume = g_object_ref (hal_volume);
       data->callback = callback;
       data->user_data = user_data;
 
@@ -907,6 +905,7 @@
 {
   EjectWrapperOp *data  = user_data;
   data->callback (data->object, res, data->user_data);
+  g_object_unref (data->object);
   g_free (data);
 }
 
@@ -927,7 +926,7 @@
   if (hal_volume->drive != NULL)
     drive = g_object_ref (hal_volume->drive);
   G_UNLOCK (hal_volume);
-  
+
   if (drive != NULL)
     {
       EjectWrapperOp *data;
@@ -986,7 +985,7 @@
   const char *label, *uuid;
 
   G_LOCK (hal_volume);
-  
+
   res = g_ptr_array_new ();
 
   g_ptr_array_add (res,
@@ -995,10 +994,10 @@
   if (hal_volume->device_path && *hal_volume->device_path != 0)
     g_ptr_array_add (res,
                      g_strdup (G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE));
-    
+
   label = hal_device_get_property_string (hal_volume->device, "volume.label");
   uuid = hal_device_get_property_string (hal_volume->device, "volume.uuid");
-  
+
   if (label && *label != 0)
     g_ptr_array_add (res,
                      g_strdup (G_VOLUME_IDENTIFIER_KIND_LABEL));
@@ -1011,7 +1010,7 @@
   g_ptr_array_add (res, NULL);
 
   G_UNLOCK (hal_volume);
-  
+
   return (char **)g_ptr_array_free (res, FALSE);
 }
 
@@ -1019,8 +1018,14 @@
 g_hal_volume_get_activation_root (GVolume *volume)
 {
   GHalVolume *hal_volume = G_HAL_VOLUME (volume);
+  GFile *root = NULL;
+
+  G_LOCK (hal_volume);
+  if (hal_volume->foreign_mount_root != NULL)
+    root = g_object_ref (hal_volume->foreign_mount_root);
+  G_UNLOCK (hal_volume);
 
-  return hal_volume->foreign_mount_root != NULL ? g_object_ref (hal_volume->foreign_mount_root) : NULL;
+  return root;
 }
 
 static void



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