[gvfs] [FTP] make the pull callback emit progress callbacks
- From: Benjamin Otte <otte src gnome org>
- To: svn-commits-list gnome org
- Subject: [gvfs] [FTP] make the pull callback emit progress callbacks
- Date: Thu, 11 Jun 2009 05:20:58 -0400 (EDT)
commit e3288d2f30f592695f3df30b60f21d37f5a64e8a
Author: Benjamin Otte <otte gnome org>
Date: Mon Jun 8 21:15:46 2009 +0200
[FTP] make the pull callback emit progress callbacks
The progress callbacks are throttled to at most once per second to not
overload dbus for very fast connections. This is implemented somewhat
ugly using a cancellable that interrupts once per second to ensure
progress updates are sent.
If someone knows a saner approach, please tell me (or better: provide a
patch).
---
daemon/gvfsbackendftp.c | 87 +++++++++++++++++++++++++++++++++++++++++------
1 files changed, 76 insertions(+), 11 deletions(-)
diff --git a/daemon/gvfsbackendftp.c b/daemon/gvfsbackendftp.c
index 9a0f08a..63bb7d0 100644
--- a/daemon/gvfsbackendftp.c
+++ b/daemon/gvfsbackendftp.c
@@ -1162,6 +1162,19 @@ out:
g_vfs_ftp_task_done (&task);
}
+static void
+cancel_timer_cb (GCancellable *orig, GCancellable *to_cancel)
+{
+ g_cancellable_cancel (to_cancel);
+}
+
+static gboolean
+cancel_cancellable (gpointer cancellable)
+{
+ g_cancellable_cancel (cancellable);
+ return FALSE;
+}
+
static gssize
ftp_output_stream_splice (GOutputStream *output,
GInputStream *input,
@@ -1174,36 +1187,88 @@ ftp_output_stream_splice (GOutputStream *output,
gssize n_read, n_written;
gssize bytes_copied;
char buffer[8192], *p;
- gboolean res;
+ GCancellable *timer_cancel;
+ gulong cancel_cb_id;
bytes_copied = 0;
+ timer_cancel = NULL;
+
for (;;)
{
- n_read = g_input_stream_read (input, buffer, sizeof (buffer), cancellable, error);
+ n_read = g_input_stream_read (input, buffer, sizeof (buffer), timer_cancel ? timer_cancel : cancellable, error);
if (n_read == -1)
- return -1;
-
+ {
+ if (g_cancellable_is_cancelled (timer_cancel) &&
+ !g_cancellable_is_cancelled (cancellable))
+ {
+ g_cancellable_disconnect (cancellable, cancel_cb_id);
+ g_object_unref (timer_cancel);
+ timer_cancel = NULL;
+ g_clear_error (error);
+ progress_callback (bytes_copied, total_size, progress_callback_data);
+ }
+ else
+ {
+ bytes_copied = -1;
+ break;
+ }
+ }
if (n_read == 0)
- return bytes_copied;
+ break;
p = buffer;
while (n_read > 0)
{
- n_written = g_output_stream_write (output, p, n_read, cancellable, error);
+ n_written = g_output_stream_write (output, p, n_read, timer_cancel ? timer_cancel : cancellable, error);
if (n_written == -1)
- return -1;
+ {
+ if (g_cancellable_is_cancelled (timer_cancel) &&
+ !g_cancellable_is_cancelled (cancellable))
+ {
+ g_cancellable_disconnect (cancellable, cancel_cb_id);
+ g_object_unref (timer_cancel);
+ timer_cancel = NULL;
+ g_clear_error (error);
+ progress_callback (bytes_copied + n_written, total_size, progress_callback_data);
+ }
+ else
+ {
+ bytes_copied = -1;
+ break;
+ }
+ }
p += n_written;
n_read -= n_written;
bytes_copied += n_written;
+ if (progress_callback && timer_cancel == NULL)
+ {
+ timer_cancel = g_cancellable_new ();
+ cancel_cb_id = g_cancellable_connect (cancellable,
+ G_CALLBACK (cancel_timer_cb),
+ timer_cancel,
+ NULL);
+ g_object_ref (timer_cancel);
+ g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
+ 1,
+ cancel_cancellable,
+ timer_cancel,
+ g_object_unref);
+ }
}
}
- while (res);
- if (res)
- return bytes_copied;
+ if (timer_cancel != NULL)
+ {
+ /* no need to remove the timeout, it'll remove itself fine and we
+ * don't get into races that way */
+ g_cancellable_disconnect (cancellable, cancel_cb_id);
+ g_object_unref (timer_cancel);
+ }
+ if (bytes_copied >= 0 && progress_callback)
+ progress_callback (bytes_copied, total_size, progress_callback_data);
- return -1;
+ return bytes_copied;
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]