[gvfs] daemon: consider all jobs excepting unmount as blocking processes



commit be4d7fa3b44a8c195bf6e19cf2a44ff9440ffc07
Author: Ondrej Holy <oholy redhat com>
Date:   Thu Feb 27 18:53:08 2014 +0100

    daemon: consider all jobs excepting unmount as blocking processes
    
    User can wait to finish all jobs (not only those with opened channel)
    before unmount to avoid potencial crashes.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=710986

 daemon/gvfsbackend.c    |   36 +++++++++---------------------------
 daemon/gvfsbackend.h    |    2 --
 daemon/gvfsdaemon.c     |   33 ++++++++++++++++++++++++++++++++-
 daemon/gvfsdaemon.h     |    1 +
 daemon/gvfsjobunmount.c |    4 ++--
 5 files changed, 44 insertions(+), 32 deletions(-)
---
diff --git a/daemon/gvfsbackend.c b/daemon/gvfsbackend.c
index 26eba28..299a9bd 100644
--- a/daemon/gvfsbackend.c
+++ b/daemon/gvfsbackend.c
@@ -856,9 +856,9 @@ on_update_processes_timeout (gpointer user_data)
 {
   UnmountWithOpData *data = user_data;
   GArray *processes;
+  GVfsDaemon *daemon = g_vfs_backend_get_daemon (data->backend);
 
-  processes = g_vfs_daemon_get_blocking_processes (g_vfs_backend_get_daemon (data->backend));
-  if (processes->len == 0)
+  if (!g_vfs_daemon_has_blocking_processes (daemon))
     {
       /* no more processes, abort mount op */
       g_mount_source_abort (data->mount_source);
@@ -868,16 +868,16 @@ on_update_processes_timeout (gpointer user_data)
   else
     {
       /* ignore reply */
+      processes = g_vfs_daemon_get_blocking_processes (daemon);
       g_mount_source_show_processes_async (data->mount_source,
                                            data->message,
                                            processes,
                                            data->choices,
                                            NULL,
                                            NULL);
+      g_array_unref (processes);
     }
 
-  g_array_unref (processes);
-
   /* keep timeout around */
   return TRUE;
 }
@@ -949,14 +949,14 @@ g_vfs_backend_unmount_with_operation (GVfsBackend        *backend,
 {
   GArray *processes;
   UnmountWithOpData *data;
+  GVfsDaemon *daemon = g_vfs_backend_get_daemon (backend);
 
   g_return_if_fail (G_VFS_IS_BACKEND (backend));
   g_return_if_fail (G_IS_MOUNT_SOURCE (mount_source));
   g_return_if_fail (callback != NULL);
 
-  processes = g_vfs_daemon_get_blocking_processes (g_vfs_backend_get_daemon (backend));
   /* if no processes are blocking, complete immediately */
-  if (processes->len == 0)
+  if (!g_vfs_daemon_has_blocking_processes (daemon))
     {
       GSimpleAsyncResult *simple;
       simple = g_simple_async_result_new (G_OBJECT (backend),
@@ -966,7 +966,7 @@ g_vfs_backend_unmount_with_operation (GVfsBackend        *backend,
       g_simple_async_result_set_op_res_gboolean (simple, TRUE);
       g_simple_async_result_complete (simple);
       g_object_unref (simple);
-      goto out;
+      return;
     }
 
   data = g_new0 (UnmountWithOpData, 1);
@@ -988,21 +988,19 @@ g_vfs_backend_unmount_with_operation (GVfsBackend        *backend,
                           (GDestroyNotify) unmount_with_op_data_free);
 
   /* show processes */
+  processes = g_vfs_daemon_get_blocking_processes (daemon);
   g_mount_source_show_processes_async (mount_source,
                                        data->message,
                                        processes,
                                        data->choices,
                                        (GAsyncReadyCallback) on_show_processes_reply,
                                        data);
+  g_array_unref (processes);
 
   /* update these processes every two secs */
   data->timeout_id = g_timeout_add_seconds (2,
                                             on_update_processes_timeout,
                                             data);
-
- out:
-  g_array_unref (processes);
-
 }
 
 static void
@@ -1044,19 +1042,3 @@ g_vfs_backend_force_unmount (GVfsBackend *backend)
                                  backend);
 }
 
-gboolean
-g_vfs_backend_has_blocking_processes (GVfsBackend  *backend)
-{
-  gboolean ret;
-  GArray *processes;
-
-  ret = FALSE;
-  processes = g_vfs_daemon_get_blocking_processes (g_vfs_backend_get_daemon (backend));
-  if (processes->len > 0)
-    ret = TRUE;
-
-  g_array_unref (processes);
-
-  return ret;
-}
-
diff --git a/daemon/gvfsbackend.h b/daemon/gvfsbackend.h
index 8e7ba55..82c8283 100644
--- a/daemon/gvfsbackend.h
+++ b/daemon/gvfsbackend.h
@@ -514,8 +514,6 @@ void        g_vfs_backend_add_auto_info                  (GVfsBackend
 void        g_vfs_backend_set_block_requests             (GVfsBackend           *backend);
 gboolean    g_vfs_backend_get_block_requests             (GVfsBackend           *backend);
 
-gboolean    g_vfs_backend_has_blocking_processes         (GVfsBackend           *backend);
-
 gboolean    g_vfs_backend_unmount_with_operation_finish (GVfsBackend  *backend,
                                                          GAsyncResult *res);
 
diff --git a/daemon/gvfsdaemon.c b/daemon/gvfsdaemon.c
index 3018e34..4e624b8 100644
--- a/daemon/gvfsdaemon.c
+++ b/daemon/gvfsdaemon.c
@@ -41,6 +41,7 @@
 #include <gvfsjobmount.h>
 #include <gvfsjobopenforread.h>
 #include <gvfsjobopenforwrite.h>
+#include <gvfsjobunmount.h>
 
 enum {
   PROP_0
@@ -1030,7 +1031,9 @@ g_vfs_daemon_initiate_mount (GVfsDaemon *daemon,
  * @daemon: A #GVfsDaemon.
  *
  * Gets all processes that blocks unmounting, e.g. processes with open
- * file handles.
+ * file handles. Returned array could be empty in spite of
+ * g_vfs_daemon_has_blocking_processes returns TRUE, because for jobs without
+ * channel we can't get #GPid.
  *
  * Returns: An array of #GPid. Free with g_array_unref().
  */
@@ -1054,6 +1057,34 @@ g_vfs_daemon_get_blocking_processes (GVfsDaemon *daemon)
   return processes;
 }
 
+/**
+ * g_vfs_daemon_has_blocking_processes:
+ * @daemon: A #GVfsDaemon.
+ *
+ * Determines if there are any jobs blocking unmounting, all jobs excepting
+ * unmount job.
+ *
+ * Returns: TRUE if there are any blocking processes, or FALSE otherwise.
+ */
+gboolean
+g_vfs_daemon_has_blocking_processes (GVfsDaemon *daemon)
+{
+  GList *l;
+
+  g_mutex_lock (&daemon->lock);
+  for (l = daemon->jobs; l != NULL; l = l->next)
+    {
+      if (!G_VFS_IS_JOB_UNMOUNT (l->data))
+        {
+          g_mutex_unlock (&daemon->lock);
+          return TRUE;
+        }
+    }
+  g_mutex_unlock (&daemon->lock);
+
+  return FALSE;
+}
+
 void
 g_vfs_daemon_run_job_in_thread (GVfsDaemon *daemon,
                                GVfsJob    *job)
diff --git a/daemon/gvfsdaemon.h b/daemon/gvfsdaemon.h
index 371dbd4..f000e2f 100644
--- a/daemon/gvfsdaemon.h
+++ b/daemon/gvfsdaemon.h
@@ -79,6 +79,7 @@ void        g_vfs_daemon_initiate_mount  (GVfsDaemon                    *daemon,
                                          GVfsDBusMountable             *object,
                                          GDBusMethodInvocation         *invocation);
 GArray     *g_vfs_daemon_get_blocking_processes (GVfsDaemon             *daemon);
+gboolean    g_vfs_daemon_has_blocking_processes (GVfsDaemon *daemon);
 void        g_vfs_daemon_run_job_in_thread      (GVfsDaemon             *daemon,
                                                 GVfsJob                *job);
 void       g_vfs_daemon_close_active_channels (GVfsDaemon                *daemon,
diff --git a/daemon/gvfsjobunmount.c b/daemon/gvfsjobunmount.c
index d97f846..205407c 100644
--- a/daemon/gvfsjobunmount.c
+++ b/daemon/gvfsjobunmount.c
@@ -188,7 +188,7 @@ job_finish_immediately_if_possible (GVfsJobUnmount *op_job)
   if (class->try_unmount != NULL || class->unmount != NULL)
     return FALSE;
 
-  is_busy = g_vfs_backend_has_blocking_processes (backend);
+  is_busy = g_vfs_daemon_has_blocking_processes (g_vfs_backend_get_daemon (backend));
   force_unmount = op_job->flags & G_MOUNT_UNMOUNT_FORCE;
 
   if (is_busy && ! force_unmount)
@@ -244,7 +244,7 @@ try (GVfsJob *job)
   gboolean is_busy;
   gboolean force_unmount;
 
-  is_busy = g_vfs_backend_has_blocking_processes (backend);
+  is_busy = g_vfs_daemon_has_blocking_processes (g_vfs_backend_get_daemon (backend));
   force_unmount = op_job->flags & G_MOUNT_UNMOUNT_FORCE;
   
   if (is_busy && ! force_unmount


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