diff options
author | Ross Lagerwall <rosslagerwall@gmail.com> | 2014-09-28 19:52:51 +0100 |
---|---|---|
committer | Ross Lagerwall <rosslagerwall@gmail.com> | 2014-10-17 20:22:26 +0100 |
commit | 5904c6d9614b48311217faac66b4e2f57174ba9d (patch) | |
tree | 0b34bc872db510284c805d46ae13b9c6d33e2a53 | |
parent | e3fab1313117d8fefc98976b8c97d0f98cbb1819 (diff) | |
download | gvfs-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.c | 6 | ||||
-rw-r--r-- | daemon/gvfsbackend.h | 3 | ||||
-rw-r--r-- | daemon/gvfsjobunmount.c | 26 |
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); |