summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoss Lagerwall <rosslagerwall@gmail.com>2014-09-28 19:52:51 +0100
committerRoss Lagerwall <rosslagerwall@gmail.com>2014-10-17 20:22:26 +0100
commit5904c6d9614b48311217faac66b4e2f57174ba9d (patch)
tree0b34bc872db510284c805d46ae13b9c6d33e2a53
parente3fab1313117d8fefc98976b8c97d0f98cbb1819 (diff)
downloadgvfs-5904c6d9614b48311217faac66b4e2f57174ba9d.tar.gz
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
-rw-r--r--daemon/gvfsbackend.c6
-rw-r--r--daemon/gvfsbackend.h3
-rw-r--r--daemon/gvfsjobunmount.c26
3 files changed, 23 insertions, 12 deletions
diff --git a/daemon/gvfsbackend.c b/daemon/gvfsbackend.c
index a143498d..633d315e 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 5908d433..6f77cf9c 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 6da8d8bf..6f6e69aa 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);