[gvfs] gvfsjobunmount: Block new requests before calling unmount() on a thread



commit 5904c6d9614b48311217faac66b4e2f57174ba9d
Author: Ross Lagerwall <rosslagerwall gmail com>
Date:   Sun Sep 28 19:52:51 2014 +0100

    gvfsjobunmount: Block new requests before calling unmount() on a thread
    
    Block new requests before calling unmount() on a separate thread to
    prevent a race where new jobs are received and processed while the
    unmount() is being executed.
    
    This is not necessary for try_unmount() because all the job handling is
    done on the same thread as the try_unmount() method and requests are
    blocked when the try_unmount() method completes.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=710986

 daemon/gvfsbackend.c    |    6 +++---
 daemon/gvfsbackend.h    |    3 ++-
 daemon/gvfsjobunmount.c |   26 ++++++++++++++++++--------
 3 files changed, 23 insertions(+), 12 deletions(-)
---
diff --git a/daemon/gvfsbackend.c b/daemon/gvfsbackend.c
index a143498..633d315 100644
--- a/daemon/gvfsbackend.c
+++ b/daemon/gvfsbackend.c
@@ -590,9 +590,9 @@ g_vfs_backend_add_auto_info (GVfsBackend *backend,
 }
 
 void
-g_vfs_backend_set_block_requests (GVfsBackend *backend)
+g_vfs_backend_set_block_requests (GVfsBackend *backend, gboolean value)
 {
-  backend->priv->block_requests = TRUE;
+  backend->priv->block_requests = value;
 }
 
 gboolean
@@ -1052,7 +1052,7 @@ forced_unregister_mount_callback (GVfsDBusMountTracker *proxy,
 void
 g_vfs_backend_force_unmount (GVfsBackend *backend)
 {
-  g_vfs_backend_set_block_requests (backend);
+  g_vfs_backend_set_block_requests (backend, TRUE);
   g_vfs_backend_unregister_mount (backend,
                                  (GAsyncReadyCallback) forced_unregister_mount_callback,
                                  backend);
diff --git a/daemon/gvfsbackend.h b/daemon/gvfsbackend.h
index 5908d43..6f77cf9 100644
--- a/daemon/gvfsbackend.h
+++ b/daemon/gvfsbackend.h
@@ -511,7 +511,8 @@ void        g_vfs_backend_add_auto_info                  (GVfsBackend
                                                          GFileInfo             *info,
                                                          const char            *uri);
 
-void        g_vfs_backend_set_block_requests             (GVfsBackend           *backend);
+void        g_vfs_backend_set_block_requests             (GVfsBackend           *backend,
+                                                          gboolean               value);
 gboolean    g_vfs_backend_get_block_requests             (GVfsBackend           *backend);
 
 gboolean    g_vfs_backend_unmount_with_operation_finish (GVfsBackend  *backend,
diff --git a/daemon/gvfsjobunmount.c b/daemon/gvfsjobunmount.c
index 6da8d8b..6f6e69a 100644
--- a/daemon/gvfsjobunmount.c
+++ b/daemon/gvfsjobunmount.c
@@ -235,9 +235,12 @@ unmount_cb (GVfsBackend  *backend,
                                              op_job->flags,
                                              op_job->mount_source);
 
-       if (run_in_thread)
-       g_vfs_daemon_run_job_in_thread (g_vfs_backend_get_daemon (backend),
-                                       G_VFS_JOB (op_job));
+      if (run_in_thread)
+        {
+          g_vfs_backend_set_block_requests (backend, TRUE);
+          g_vfs_daemon_run_job_in_thread (g_vfs_backend_get_daemon (backend),
+                                          G_VFS_JOB (op_job));
+        }
     }
 }
 
@@ -275,7 +278,12 @@ try (GVfsJob *job)
                               op_job->flags,
                               op_job->mount_source);
   else
-    return FALSE;
+    {
+      /* We're going to run the backend's unmount method on a thread, block
+       * new jobs coming in. */
+      g_vfs_backend_set_block_requests (backend, TRUE);
+      return FALSE;
+    }
 }
 
 static void
@@ -314,18 +322,20 @@ static void
 send_reply (GVfsJob *job)
 {
   GVfsJobUnmount *op_job = G_VFS_JOB_UNMOUNT (job);
+  GVfsBackend *backend = op_job->backend;
 
   g_debug ("send_reply, failed: %d\n", job->failed);
 
   if (job->failed)
-    (*G_VFS_JOB_CLASS (g_vfs_job_unmount_parent_class)->send_reply) (G_VFS_JOB (op_job));
+    {
+      g_vfs_backend_set_block_requests (backend, FALSE);
+      (*G_VFS_JOB_CLASS (g_vfs_job_unmount_parent_class)->send_reply) (G_VFS_JOB (op_job));
+    }
   else
     {
-      GVfsBackend *backend = op_job->backend;
-
       /* Setting the backend to block requests will also
          set active GVfsChannels to block requets  */
-      g_vfs_backend_set_block_requests (backend);
+      g_vfs_backend_set_block_requests (backend, TRUE);
       g_vfs_backend_unregister_mount (backend,
                                      (GAsyncReadyCallback) unregister_mount_callback,
                                      job);


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