[gvfs/wip/oholy/google-progress: 1/3] google: Report progress for file transfers from local filesystem
- From: Ondrej Holy <oholy src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gvfs/wip/oholy/google-progress: 1/3] google: Report progress for file transfers from local filesystem
- Date: Mon, 5 Oct 2020 11:27:18 +0000 (UTC)
commit cec64e3a671292c3cf13db5c0696d08dd4d69635
Author: Ondrej Holy <oholy redhat com>
Date: Mon Oct 5 11:20:06 2020 +0200
google: Report progress for file transfers from local filesystem
Google backend doesn't report progress from push job. As a consequence,
Nautilus shows wierd time estimations when moving/copying file from
local filesystem. Let's add custom splice function and report progress
from it.
Fixes: https://gitlab.gnome.org/GNOME/gvfs/-/issues/463
daemon/gvfsbackendgoogle.c | 20 +++++++------
daemon/gvfsdaemonutils.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++
daemon/gvfsdaemonutils.h | 9 ++++++
3 files changed, 94 insertions(+), 9 deletions(-)
---
diff --git a/daemon/gvfsbackendgoogle.c b/daemon/gvfsbackendgoogle.c
index 27c9eba0..c9ef3a24 100644
--- a/daemon/gvfsbackendgoogle.c
+++ b/daemon/gvfsbackendgoogle.c
@@ -49,6 +49,7 @@
#include "gvfsjobsetdisplayname.h"
#include "gvfsjobwrite.h"
#include "gvfsmonitor.h"
+#include "gvfsdaemonutils.h"
struct _GVfsBackendGoogle
{
@@ -2772,7 +2773,6 @@ g_vfs_backend_google_push (GVfsBackend *_self,
gchar *entry_path = NULL;
gchar *parent_path = NULL;
gchar *local_file_title = NULL;
- goffset size;
g_rec_mutex_lock (&self->mutex);
g_debug ("+ push: %s -> %s, %d\n", local_path, destination, flags);
@@ -2799,7 +2799,8 @@ g_vfs_backend_google_push (GVfsBackend *_self,
info = g_file_query_info (local_file,
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE","
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME","
- G_FILE_ATTRIBUTE_STANDARD_TYPE,
+ G_FILE_ATTRIBUTE_STANDARD_TYPE","
+ G_FILE_ATTRIBUTE_STANDARD_SIZE,
G_FILE_QUERY_INFO_NONE,
cancellable,
&error);
@@ -2975,11 +2976,14 @@ g_vfs_backend_google_push (GVfsBackend *_self,
}
error = NULL;
- g_output_stream_splice (G_OUTPUT_STREAM (ostream),
- G_INPUT_STREAM (istream),
- G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
- cancellable,
- &error);
+ gvfs_output_stream_splice (G_OUTPUT_STREAM (ostream),
+ G_INPUT_STREAM (istream),
+ G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
+ g_file_info_get_size (info),
+ progress_callback,
+ progress_callback_data,
+ cancellable,
+ &error);
if (error != NULL)
{
g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
@@ -3018,8 +3022,6 @@ g_vfs_backend_google_push (GVfsBackend *_self,
}
}
- size = gdata_documents_entry_get_file_size (GDATA_DOCUMENTS_ENTRY (new_document));
- g_vfs_job_progress_callback (size, size, job);
g_vfs_job_succeeded (G_VFS_JOB (job));
out:
diff --git a/daemon/gvfsdaemonutils.c b/daemon/gvfsdaemonutils.c
index 5292ba4a..3337d22a 100644
--- a/daemon/gvfsdaemonutils.c
+++ b/daemon/gvfsdaemonutils.c
@@ -361,3 +361,77 @@ gvfs_accept_certificate (GMountSource *mount_source,
return FALSE;
}
#endif
+
+gssize
+gvfs_output_stream_splice (GOutputStream *stream,
+ GInputStream *source,
+ GOutputStreamSpliceFlags flags,
+ goffset total_size,
+ GFileProgressCallback progress_callback,
+ gpointer progress_callback_data,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gssize n_read, n_written;
+ gsize bytes_copied;
+ char buffer[8192], *p;
+ gboolean res;
+
+ bytes_copied = 0;
+ res = TRUE;
+ do
+ {
+ n_read = g_input_stream_read (source, buffer, sizeof (buffer), cancellable, error);
+ if (n_read == -1)
+ {
+ res = FALSE;
+ break;
+ }
+
+ if (n_read == 0)
+ break;
+
+ p = buffer;
+ while (n_read > 0)
+ {
+ n_written = g_output_stream_write (stream, p, n_read, cancellable, error);
+ if (n_written == -1)
+ {
+ res = FALSE;
+ break;
+ }
+
+ p += n_written;
+ n_read -= n_written;
+ bytes_copied += n_written;
+
+ if (progress_callback)
+ progress_callback (bytes_copied, total_size, progress_callback_data);
+ }
+
+ if (bytes_copied > G_MAXSSIZE)
+ bytes_copied = G_MAXSSIZE;
+ }
+ while (res);
+
+ if (!res)
+ error = NULL; /* Ignore further errors */
+
+ if (flags & G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE)
+ {
+ /* Don't care about errors in source here */
+ g_input_stream_close (source, cancellable, NULL);
+ }
+
+ if (flags & G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET)
+ {
+ /* But write errors on close are bad! */
+ if (!g_output_stream_close (stream, cancellable, error))
+ res = FALSE;
+ }
+
+ if (res)
+ return bytes_copied;
+
+ return -1;
+}
diff --git a/daemon/gvfsdaemonutils.h b/daemon/gvfsdaemonutils.h
index 73ec0c0c..1256a615 100644
--- a/daemon/gvfsdaemonutils.h
+++ b/daemon/gvfsdaemonutils.h
@@ -47,6 +47,15 @@ gboolean gvfs_accept_certificate (GMountSource *mount_source,
GTlsCertificate *certificate,
GTlsCertificateFlags errors);
+gssize gvfs_output_stream_splice (GOutputStream *stream,
+ GInputStream *source,
+ GOutputStreamSpliceFlags flags,
+ goffset total_size,
+ GFileProgressCallback progress_callback,
+ gpointer progress_callback_data,
+ GCancellable *cancellable,
+ GError **error);
+
G_END_DECLS
#endif /* __G_VFS_DAEMON_UTILS_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]