diff options
author | Ross Lagerwall <rosslagerwall@gmail.com> | 2013-09-21 22:22:27 +0200 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2013-09-30 10:48:09 +0200 |
commit | bdc3babbe21e5fed06876db4d56d1b13915fe1cb (patch) | |
tree | cc894424b80866d330faadf67e1e7d03e4f151c3 | |
parent | a1dd98ffa979441a0b9db3289287eaeab2c1aadf (diff) | |
download | gvfs-bdc3babbe21e5fed06876db4d56d1b13915fe1cb.tar.gz |
daemon: Emit signal before returning dbus value
In gvfsjobopenforread.c, the dbus method returns a value in create_reply
which eventually results in a GVfsJobRead job to be sent to the backend.
This could happen before the "new-source" signal is emitted. If this
happens, the job is not queued because the "new_job" signal would not
have been connected to a job source yet. The read then hangs because
the GVfsJobRead is lost.
This is hit often when performing large smb transfers (see
https://bugzilla.gnome.org/show_bug.cgi?id=697782 and
https://bugs.launchpad.net/ubuntu/+source/gvfs/+bug/1075923).
It can be reproduced by putting a small sleep before the
g_signal_emit_by_name call.
Fix this by emitting the "new-source" signal *before* the dbus method
value is returned. This ensures that the "new_job" signal is set up
before any further jobs are sent.
Note that the same problem and solution applies for
gvfsjobopenforwrite.c.
-rw-r--r-- | daemon/gvfsjobopenforread.c | 12 | ||||
-rw-r--r-- | daemon/gvfsjobopenforwrite.c | 12 |
2 files changed, 12 insertions, 12 deletions
diff --git a/daemon/gvfsjobopenforread.c b/daemon/gvfsjobopenforread.c index d9781365..41b5f34d 100644 --- a/daemon/gvfsjobopenforread.c +++ b/daemon/gvfsjobopenforread.c @@ -194,6 +194,12 @@ create_reply (GVfsJob *job, g_error_free (error); } + g_vfs_channel_set_backend_handle (G_VFS_CHANNEL (channel), open_job->backend_handle); + open_job->backend_handle = NULL; + open_job->read_channel = channel; + + g_signal_emit_by_name (job, "new-source", channel); + if (open_job->read_icon) gvfs_dbus_mount_complete_open_icon_for_read (object, invocation, fd_list, g_variant_new_handle (fd_id), @@ -206,12 +212,6 @@ create_reply (GVfsJob *job, /* FIXME: this could cause issues as long as fd_list closes all its fd's when it's finalized */ close (remote_fd); g_object_unref (fd_list); - - g_vfs_channel_set_backend_handle (G_VFS_CHANNEL (channel), open_job->backend_handle); - open_job->backend_handle = NULL; - open_job->read_channel = channel; - - g_signal_emit_by_name (job, "new-source", open_job->read_channel); } static void diff --git a/daemon/gvfsjobopenforwrite.c b/daemon/gvfsjobopenforwrite.c index a63e9cd8..429e2679 100644 --- a/daemon/gvfsjobopenforwrite.c +++ b/daemon/gvfsjobopenforwrite.c @@ -278,6 +278,12 @@ create_reply (GVfsJob *job, g_error_free (error); } + g_vfs_channel_set_backend_handle (G_VFS_CHANNEL (channel), open_job->backend_handle); + open_job->backend_handle = NULL; + open_job->write_channel = channel; + + g_signal_emit_by_name (job, "new-source", open_job->write_channel); + gvfs_dbus_mount_complete_open_for_write (object, invocation, fd_list, g_variant_new_handle (fd_id), open_job->can_seek, @@ -285,12 +291,6 @@ create_reply (GVfsJob *job, close (remote_fd); g_object_unref (fd_list); - - g_vfs_channel_set_backend_handle (G_VFS_CHANNEL (channel), open_job->backend_handle); - open_job->backend_handle = NULL; - open_job->write_channel = channel; - - g_signal_emit_by_name (job, "new-source", open_job->write_channel); } static void |