diff options
author | Tomas Bzatek <tbzatek@redhat.com> | 2012-06-29 16:26:13 +0200 |
---|---|---|
committer | Tomas Bzatek <tbzatek@redhat.com> | 2012-07-31 11:59:37 +0200 |
commit | 918cebfd9b96b22179b4685d94e72b6c97090eb3 (patch) | |
tree | eb9e5b61359da95110cc68626b3504d82b22b079 | |
parent | 17a008f395c438c0dad394523cc3d62261ceca4a (diff) | |
download | gvfs-918cebfd9b96b22179b4685d94e72b6c97090eb3.tar.gz |
gdbus: Make copy progress work
...by turning sync copy calls async and running mainloop for progress
interface skeleton be able to process incoming calls.
Also, new class GVfsJobProgress has been introduced mostly for code sharing.
-rw-r--r-- | client/gdaemonfile.c | 138 | ||||
-rw-r--r-- | daemon/Makefile.am | 1 | ||||
-rw-r--r-- | daemon/gvfsbackendsftp.c | 3 | ||||
-rw-r--r-- | daemon/gvfsjobcopy.c | 123 | ||||
-rw-r--r-- | daemon/gvfsjobcopy.h | 7 | ||||
-rw-r--r-- | daemon/gvfsjobmove.c | 122 | ||||
-rw-r--r-- | daemon/gvfsjobmove.h | 7 | ||||
-rw-r--r-- | daemon/gvfsjobpull.c | 126 | ||||
-rw-r--r-- | daemon/gvfsjobpull.h | 7 | ||||
-rw-r--r-- | daemon/gvfsjobpush.c | 126 | ||||
-rw-r--r-- | daemon/gvfsjobpush.h | 7 |
11 files changed, 226 insertions, 441 deletions
diff --git a/client/gdaemonfile.c b/client/gdaemonfile.c index b60e6725..5ffd1a71 100644 --- a/client/gdaemonfile.c +++ b/client/gdaemonfile.c @@ -2787,20 +2787,23 @@ g_daemon_file_set_attribute (GFile *file, return TRUE; } -typedef struct { + +typedef struct +{ + GAsyncResult *res; + GMainContext *context; + GMainLoop *loop; GFileProgressCallback progress_callback; gpointer progress_callback_data; -} ProgressCallbackData; +} FileTransferSyncData; static gboolean handle_progress (GVfsDBusProgress *object, GDBusMethodInvocation *invocation, guint64 arg_current, guint64 arg_total, - ProgressCallbackData *data) + FileTransferSyncData *data) { - g_print ("handle_progress\n"); - data->progress_callback (arg_current, arg_total, data->progress_callback_data); gvfs_dbus_progress_complete_progress (object, invocation); @@ -2808,6 +2811,17 @@ handle_progress (GVfsDBusProgress *object, return TRUE; } +static void +copy_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + FileTransferSyncData *data = user_data; + + data->res = g_object_ref (res); + g_main_loop_quit (data->loop); +} + static gboolean file_transfer (GFile *source, GFile *destination, @@ -2819,7 +2833,7 @@ file_transfer (GFile *source, GError **error) { char *obj_path; - ProgressCallbackData data; + FileTransferSyncData data = {0, }; char *local_path = NULL; gboolean source_is_daemon; gboolean dest_is_daemon; @@ -2863,14 +2877,11 @@ file_transfer (GFile *source, } - if (progress_callback) + if (send_progress) obj_path = g_strdup_printf ("/org/gtk/vfs/callback/%p", &obj_path); else obj_path = g_strdup ("/org/gtk/vfs/void"); - data.progress_callback = progress_callback; - data.progress_callback_data = progress_callback_data; - /* need to create proxy with daemon files only */ if (native_transfer) { @@ -2904,69 +2915,98 @@ retry: if (proxy == NULL) goto out; - /* Register progress interface skeleton */ - progress_skeleton = gvfs_dbus_progress_skeleton_new (); - g_dbus_interface_skeleton_set_flags (G_DBUS_INTERFACE_SKELETON (progress_skeleton), G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD); - g_signal_connect (progress_skeleton, "handle-progress", G_CALLBACK (handle_progress), &data); + data.progress_callback = progress_callback; + data.progress_callback_data = progress_callback_data; + data.context = g_main_context_new (); + data.loop = g_main_loop_new (data.context, FALSE); - if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (progress_skeleton), - connection, - obj_path, - &my_error)) - goto out; + g_main_context_push_thread_default (data.context); + + if (send_progress) + { + /* Register progress interface skeleton */ + progress_skeleton = gvfs_dbus_progress_skeleton_new (); + g_signal_connect (progress_skeleton, "handle-progress", G_CALLBACK (handle_progress), &data); + + if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (progress_skeleton), + connection, + obj_path, + &my_error)) + goto out; + } if (native_transfer == TRUE) { if (remove_source == FALSE) { - res = gvfs_dbus_mount_call_copy_sync (proxy, - path1, path2, - flags, - obj_path, - cancellable, - &my_error); + gvfs_dbus_mount_call_copy (proxy, + path1, path2, + flags, + obj_path, + cancellable, + copy_cb, + &data); + g_main_loop_run (data.loop); + res = gvfs_dbus_mount_call_copy_finish (proxy, data.res, &my_error); } else { - res = gvfs_dbus_mount_call_move_sync (proxy, - path1, path2, - flags, - obj_path, - cancellable, - &my_error); + gvfs_dbus_mount_call_move (proxy, + path1, path2, + flags, + obj_path, + cancellable, + copy_cb, + &data); + g_main_loop_run (data.loop); + res = gvfs_dbus_mount_call_move_finish (proxy, data.res, &my_error); } } else if (dest_is_daemon == TRUE) { - res = gvfs_dbus_mount_call_push_sync (proxy, - path1, - local_path, - send_progress, - flags, - obj_path, - remove_source, - cancellable, - &my_error); + gvfs_dbus_mount_call_push (proxy, + path1, + local_path, + send_progress, + flags, + obj_path, + remove_source, + cancellable, + copy_cb, + &data); + g_main_loop_run (data.loop); + res = gvfs_dbus_mount_call_push_finish (proxy, data.res, &my_error); } else { - res = gvfs_dbus_mount_call_pull_sync (proxy, - path1, - local_path, - send_progress, - flags, - obj_path, - remove_source, - cancellable, - &my_error); + gvfs_dbus_mount_call_pull (proxy, + path1, + local_path, + send_progress, + flags, + obj_path, + remove_source, + cancellable, + copy_cb, + &data); + g_main_loop_run (data.loop); + res = gvfs_dbus_mount_call_pull_finish (proxy, data.res, &my_error); } + g_object_unref (data.res); + out: if (progress_skeleton) { g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (progress_skeleton)); g_object_unref (progress_skeleton); } + if (data.context) + { + g_main_context_pop_thread_default (data.context); + g_main_context_unref (data.context); + g_main_loop_unref (data.loop); + } if (! res) { diff --git a/daemon/Makefile.am b/daemon/Makefile.am index b6e999ce..bc9da0a1 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -149,6 +149,7 @@ libdaemon_la_SOURCES = \ gvfsjob.c gvfsjob.h \ gvfsjobsource.c gvfsjobsource.h \ gvfsjobdbus.c gvfsjobdbus.h \ + gvfsjobprogress.c gvfsjobprogress.h \ gvfsjobmount.c gvfsjobmount.h \ gvfsjobunmount.c gvfsjobunmount.h \ gvfsjobmountmountable.c gvfsjobmountmountable.h \ diff --git a/daemon/gvfsbackendsftp.c b/daemon/gvfsbackendsftp.c index 08c7c2a5..672f8d49 100644 --- a/daemon/gvfsbackendsftp.c +++ b/daemon/gvfsbackendsftp.c @@ -61,6 +61,7 @@ #include "gvfsjobqueryattributes.h" #include "gvfsjobenumerate.h" #include "gvfsjobmakedirectory.h" +#include "gvfsjobprogress.h" #include "gvfsdaemonprotocol.h" #include "gvfskeyring.h" #include "sftp.h" @@ -4163,7 +4164,7 @@ move_reply (GVfsBackendSftp *backend, /* Succeeded, report file size */ file_size = job->backend_data; if (file_size != NULL) - g_vfs_job_move_progress_callback (*file_size, *file_size, job); + g_vfs_job_progress_callback (*file_size, *file_size, job); g_vfs_job_succeeded (job); } } diff --git a/daemon/gvfsjobcopy.c b/daemon/gvfsjobcopy.c index 9be8472a..6320ca04 100644 --- a/daemon/gvfsjobcopy.c +++ b/daemon/gvfsjobcopy.c @@ -33,7 +33,7 @@ #include "gvfsjobcopy.h" #include <gvfsdbus.h> -G_DEFINE_TYPE (GVfsJobCopy, g_vfs_job_copy, G_VFS_TYPE_JOB_DBUS) +G_DEFINE_TYPE (GVfsJobCopy, g_vfs_job_copy, G_VFS_TYPE_JOB_PROGRESS) static void run (GVfsJob *job); static gboolean try (GVfsJob *job); @@ -50,7 +50,6 @@ g_vfs_job_copy_finalize (GObject *object) g_free (job->source); g_free (job->destination); - g_free (job->callback_obj_path); if (G_OBJECT_CLASS (g_vfs_job_copy_parent_class)->finalize) (*G_OBJECT_CLASS (g_vfs_job_copy_parent_class)->finalize) (object); @@ -84,7 +83,8 @@ g_vfs_job_copy_new_handle (GVfsDBusMount *object, GVfsBackend *backend) { GVfsJobCopy *job; - + GVfsJobProgress *progress_job; + g_print ("called Copy()\n"); if (g_vfs_backend_invocation_first_handler (object, invocation, backend)) @@ -94,13 +94,15 @@ g_vfs_job_copy_new_handle (GVfsDBusMount *object, "object", object, "invocation", invocation, NULL); + progress_job = G_VFS_JOB_PROGRESS (job); job->source = g_strdup (arg_path1_data); job->destination = g_strdup (arg_path2_data); job->backend = backend; job->flags = arg_flags; if (strcmp (arg_progress_obj_path, "/org/gtk/vfs/void") != 0) - job->callback_obj_path = g_strdup (arg_progress_obj_path); + progress_job->callback_obj_path = g_strdup (arg_progress_obj_path); + progress_job->send_progress = progress_job->callback_obj_path != NULL; g_vfs_job_source_new_job (G_VFS_JOB_SOURCE (backend), G_VFS_JOB (job)); g_object_unref (job); @@ -108,90 +110,11 @@ g_vfs_job_copy_new_handle (GVfsDBusMount *object, return TRUE; } -typedef struct { - goffset current_num_bytes; - goffset total_num_bytes; -} ProgressCallbackData; - -static void -progress_cb (GVfsDBusProgress *proxy, - GAsyncResult *res, - gpointer user_data) -{ - GError *error = NULL; - - g_print ("progress_cb\n"); - - if (! gvfs_dbus_progress_call_progress_finish (proxy, res, &error)) - { - g_warning ("progress_cb: %s (%s, %d)\n", error->message, g_quark_to_string (error->domain), error->code); - g_error_free (error); - } -} - -static void -progress_proxy_new_cb (GObject *source_object, - GAsyncResult *res, - gpointer user_data) -{ - ProgressCallbackData *data = user_data; - GVfsDBusProgress *proxy; - GError *error = NULL; - - g_print ("progress_proxy_new_cb\n"); - - proxy = gvfs_dbus_progress_proxy_new_finish (res, &error); - if (proxy == NULL) - { - g_warning ("progress_proxy_new_cb: %s (%s, %d)\n", error->message, g_quark_to_string (error->domain), error->code); - g_error_free (error); - goto out; - } - - gvfs_dbus_progress_call_progress (proxy, - data->current_num_bytes, - data->total_num_bytes, - NULL, - (GAsyncReadyCallback) progress_cb, - NULL); - g_object_unref (proxy); - - out: - g_free (data); -} - -static void -progress_callback (goffset current_num_bytes, - goffset total_num_bytes, - gpointer user_data) -{ - GVfsJob *job = G_VFS_JOB (user_data); - GVfsJobDBus *dbus_job = G_VFS_JOB_DBUS (job); - GVfsJobCopy *op_job = G_VFS_JOB_COPY (job); - ProgressCallbackData *data; - - g_debug ("progress_callback %" G_GOFFSET_FORMAT "/%" G_GOFFSET_FORMAT "\n", current_num_bytes, total_num_bytes); - - if (op_job->callback_obj_path == NULL) - return; - - data = g_new0 (ProgressCallbackData, 1); - data->current_num_bytes = current_num_bytes; - data->total_num_bytes = total_num_bytes; - - gvfs_dbus_progress_proxy_new (g_dbus_method_invocation_get_connection (dbus_job->invocation), - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, - g_dbus_method_invocation_get_sender (dbus_job->invocation), - op_job->callback_obj_path, - NULL, - progress_proxy_new_cb, - data); -} - static void run (GVfsJob *job) { GVfsJobCopy *op_job = G_VFS_JOB_COPY (job); + GVfsJobProgress *progress_job = G_VFS_JOB_PROGRESS (job); GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); if (class->copy == NULL) @@ -201,31 +124,45 @@ run (GVfsJob *job) return; } + g_vfs_job_progress_construct_proxy (job); + class->copy (op_job->backend, op_job, op_job->source, op_job->destination, op_job->flags, - progress_callback, - job); + progress_job->send_progress ? g_vfs_job_progress_callback : NULL, + progress_job->send_progress ? job : NULL); + + if (progress_job->progress_proxy) + g_clear_object (&progress_job->progress_proxy); } static gboolean try (GVfsJob *job) { GVfsJobCopy *op_job = G_VFS_JOB_COPY (job); + GVfsJobProgress *progress_job = G_VFS_JOB_PROGRESS (job); GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); + gboolean res; if (class->try_copy == NULL) return FALSE; - return class->try_copy (op_job->backend, - op_job, - op_job->source, - op_job->destination, - op_job->flags, - progress_callback, - job); + g_vfs_job_progress_construct_proxy (job); + + res = class->try_copy (op_job->backend, + op_job, + op_job->source, + op_job->destination, + op_job->flags, + progress_job->send_progress ? g_vfs_job_progress_callback : NULL, + progress_job->send_progress ? job : NULL); + + if (progress_job->progress_proxy) + g_clear_object (&progress_job->progress_proxy); + + return res; } /* Might be called on an i/o thread */ diff --git a/daemon/gvfsjobcopy.h b/daemon/gvfsjobcopy.h index 322d2c71..bb575c51 100644 --- a/daemon/gvfsjobcopy.h +++ b/daemon/gvfsjobcopy.h @@ -27,6 +27,7 @@ #include <gvfsjob.h> #include <gvfsjobdbus.h> #include <gvfsbackend.h> +#include <gvfsjobprogress.h> G_BEGIN_DECLS @@ -41,19 +42,17 @@ typedef struct _GVfsJobCopyClass GVfsJobCopyClass; struct _GVfsJobCopy { - GVfsJobDBus parent_instance; + GVfsJobProgress parent_instance; GVfsBackend *backend; char *source; char *destination; GFileCopyFlags flags; - char *callback_obj_path; - }; struct _GVfsJobCopyClass { - GVfsJobDBusClass parent_class; + GVfsJobProgressClass parent_class; }; GType g_vfs_job_copy_get_type (void) G_GNUC_CONST; diff --git a/daemon/gvfsjobmove.c b/daemon/gvfsjobmove.c index bac56188..c74f074f 100644 --- a/daemon/gvfsjobmove.c +++ b/daemon/gvfsjobmove.c @@ -33,7 +33,7 @@ #include "gvfsjobmove.h" #include "gvfsdbus.h" -G_DEFINE_TYPE (GVfsJobMove, g_vfs_job_move, G_VFS_TYPE_JOB_DBUS) +G_DEFINE_TYPE (GVfsJobMove, g_vfs_job_move, G_VFS_TYPE_JOB_PROGRESS) static void run (GVfsJob *job); static gboolean try (GVfsJob *job); @@ -50,7 +50,6 @@ g_vfs_job_move_finalize (GObject *object) g_free (job->source); g_free (job->destination); - g_free (job->callback_obj_path); if (G_OBJECT_CLASS (g_vfs_job_move_parent_class)->finalize) (*G_OBJECT_CLASS (g_vfs_job_move_parent_class)->finalize) (object); @@ -84,7 +83,8 @@ g_vfs_job_move_new_handle (GVfsDBusMount *object, GVfsBackend *backend) { GVfsJobMove *job; - + GVfsJobProgress *progress_job; + g_print ("called Move()\n"); if (g_vfs_backend_invocation_first_handler (object, invocation, backend)) @@ -94,13 +94,15 @@ g_vfs_job_move_new_handle (GVfsDBusMount *object, "object", object, "invocation", invocation, NULL); + progress_job = G_VFS_JOB_PROGRESS (job); job->source = g_strdup (arg_path1_data); job->destination = g_strdup (arg_path2_data); job->backend = backend; job->flags = arg_flags; if (strcmp (arg_progress_obj_path, "/org/gtk/vfs/void") != 0) - job->callback_obj_path = g_strdup (arg_progress_obj_path); + progress_job->callback_obj_path = g_strdup (arg_progress_obj_path); + progress_job->send_progress = progress_job->callback_obj_path != NULL; g_vfs_job_source_new_job (G_VFS_JOB_SOURCE (backend), G_VFS_JOB (job)); g_object_unref (job); @@ -108,89 +110,11 @@ g_vfs_job_move_new_handle (GVfsDBusMount *object, return TRUE; } -typedef struct { - goffset current_num_bytes; - goffset total_num_bytes; -} ProgressCallbackData; - -static void -progress_cb (GVfsDBusProgress *proxy, - GAsyncResult *res, - gpointer user_data) -{ - GError *error = NULL; - - g_print ("progress_cb\n"); - - if (! gvfs_dbus_progress_call_progress_finish (proxy, res, &error)) - { - g_warning ("progress_cb: %s (%s, %d)\n", error->message, g_quark_to_string (error->domain), error->code); - g_error_free (error); - } -} - -static void -progress_proxy_new_cb (GObject *source_object, - GAsyncResult *res, - gpointer user_data) -{ - ProgressCallbackData *data = user_data; - GVfsDBusProgress *proxy; - GError *error = NULL; - - g_print ("progress_proxy_new_cb\n"); - - proxy = gvfs_dbus_progress_proxy_new_finish (res, &error); - if (proxy == NULL) - { - g_warning ("progress_proxy_new_cb: %s (%s, %d)\n", error->message, g_quark_to_string (error->domain), error->code); - g_error_free (error); - goto out; - } - - gvfs_dbus_progress_call_progress (proxy, - data->current_num_bytes, - data->total_num_bytes, - NULL, - (GAsyncReadyCallback) progress_cb, - NULL); - g_object_unref (proxy); - - out: - g_free (data); -} - -void -g_vfs_job_move_progress_callback (goffset current_num_bytes, - goffset total_num_bytes, - GVfsJob *job) -{ - GVfsJobDBus *dbus_job = G_VFS_JOB_DBUS (job); - GVfsJobMove *op_job = G_VFS_JOB_MOVE (job); - ProgressCallbackData *data; - - g_debug ("progress_callback %" G_GOFFSET_FORMAT "/%" G_GOFFSET_FORMAT "\n", current_num_bytes, total_num_bytes); - - if (op_job->callback_obj_path == NULL) - return; - - data = g_new0 (ProgressCallbackData, 1); - data->current_num_bytes = current_num_bytes; - data->total_num_bytes = total_num_bytes; - - gvfs_dbus_progress_proxy_new (g_dbus_method_invocation_get_connection (dbus_job->invocation), - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, - g_dbus_method_invocation_get_sender (dbus_job->invocation), - op_job->callback_obj_path, - NULL, - progress_proxy_new_cb, - data); -} - static void run (GVfsJob *job) { GVfsJobMove *op_job = G_VFS_JOB_MOVE (job); + GVfsJobProgress *progress_job = G_VFS_JOB_PROGRESS (job); GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); if (class->move == NULL) @@ -200,31 +124,45 @@ run (GVfsJob *job) return; } + g_vfs_job_progress_construct_proxy (job); + class->move (op_job->backend, op_job, op_job->source, op_job->destination, op_job->flags, - (GFileProgressCallback)g_vfs_job_move_progress_callback, - job); + progress_job->send_progress ? g_vfs_job_progress_callback : NULL, + progress_job->send_progress ? job : NULL); + + if (progress_job->progress_proxy) + g_clear_object (&progress_job->progress_proxy); } static gboolean try (GVfsJob *job) { GVfsJobMove *op_job = G_VFS_JOB_MOVE (job); + GVfsJobProgress *progress_job = G_VFS_JOB_PROGRESS (job); GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); + gboolean res; if (class->try_move == NULL) return FALSE; - return class->try_move (op_job->backend, - op_job, - op_job->source, - op_job->destination, - op_job->flags, - (GFileProgressCallback)g_vfs_job_move_progress_callback, - job); + g_vfs_job_progress_construct_proxy (job); + + res = class->try_move (op_job->backend, + op_job, + op_job->source, + op_job->destination, + op_job->flags, + progress_job->send_progress ? g_vfs_job_progress_callback : NULL, + progress_job->send_progress ? job : NULL); + + if (progress_job->progress_proxy) + g_clear_object (&progress_job->progress_proxy); + + return res; } /* Might be called on an i/o thread */ diff --git a/daemon/gvfsjobmove.h b/daemon/gvfsjobmove.h index b1eec943..7b189001 100644 --- a/daemon/gvfsjobmove.h +++ b/daemon/gvfsjobmove.h @@ -27,6 +27,7 @@ #include <gvfsjob.h> #include <gvfsjobdbus.h> #include <gvfsbackend.h> +#include <gvfsjobprogress.h> G_BEGIN_DECLS @@ -41,19 +42,17 @@ typedef struct _GVfsJobMoveClass GVfsJobMoveClass; struct _GVfsJobMove { - GVfsJobDBus parent_instance; + GVfsJobProgress parent_instance; GVfsBackend *backend; char *source; char *destination; GFileCopyFlags flags; - char *callback_obj_path; - }; struct _GVfsJobMoveClass { - GVfsJobDBusClass parent_class; + GVfsJobProgressClass parent_class; }; GType g_vfs_job_move_get_type (void) G_GNUC_CONST; diff --git a/daemon/gvfsjobpull.c b/daemon/gvfsjobpull.c index 3dda992c..843d6f65 100644 --- a/daemon/gvfsjobpull.c +++ b/daemon/gvfsjobpull.c @@ -33,7 +33,7 @@ #include "gvfsjobpull.h" #include "gvfsdbus.h" -G_DEFINE_TYPE (GVfsJobPull, g_vfs_job_pull, G_VFS_TYPE_JOB_DBUS) +G_DEFINE_TYPE (GVfsJobPull, g_vfs_job_pull, G_VFS_TYPE_JOB_PROGRESS) static void run (GVfsJob *job); static gboolean try (GVfsJob *job); @@ -50,7 +50,6 @@ g_vfs_job_pull_finalize (GObject *object) g_free (job->local_path); g_free (job->source); - g_free (job->callback_obj_path); if (G_OBJECT_CLASS (g_vfs_job_pull_parent_class)->finalize) (*G_OBJECT_CLASS (g_vfs_job_pull_parent_class)->finalize) (object); @@ -86,7 +85,8 @@ g_vfs_job_pull_new_handle (GVfsDBusMount *object, GVfsBackend *backend) { GVfsJobPull *job; - + GVfsJobProgress *progress_job; + g_print ("called Pull()\n"); if (g_vfs_backend_invocation_first_handler (object, invocation, backend)) @@ -96,16 +96,17 @@ g_vfs_job_pull_new_handle (GVfsDBusMount *object, "object", object, "invocation", invocation, NULL); + progress_job = G_VFS_JOB_PROGRESS (job); job->source = g_strdup (arg_path_data); job->local_path = g_strdup (arg_local_path); job->backend = backend; job->flags = arg_flags; - job->send_progress = arg_send_progress; + progress_job->send_progress = arg_send_progress; job->remove_source = arg_remove_source; g_debug ("Remove Source: %s\n", arg_remove_source ? "true" : "false"); if (strcmp (arg_progress_obj_path, "/org/gtk/vfs/void") != 0) - job->callback_obj_path = g_strdup (arg_progress_obj_path); + progress_job->callback_obj_path = g_strdup (arg_progress_obj_path); g_vfs_job_source_new_job (G_VFS_JOB_SOURCE (backend), G_VFS_JOB (job)); g_object_unref (job); @@ -113,90 +114,11 @@ g_vfs_job_pull_new_handle (GVfsDBusMount *object, return TRUE; } -typedef struct { - goffset current_num_bytes; - goffset total_num_bytes; -} ProgressCallbackData; - -static void -progress_cb (GVfsDBusProgress *proxy, - GAsyncResult *res, - gpointer user_data) -{ - GError *error = NULL; - - g_print ("progress_cb\n"); - - if (! gvfs_dbus_progress_call_progress_finish (proxy, res, &error)) - { - g_warning ("progress_cb: %s (%s, %d)\n", error->message, g_quark_to_string (error->domain), error->code); - g_error_free (error); - } -} - -static void -progress_proxy_new_cb (GObject *source_object, - GAsyncResult *res, - gpointer user_data) -{ - ProgressCallbackData *data = user_data; - GVfsDBusProgress *proxy; - GError *error = NULL; - - g_print ("progress_proxy_new_cb\n"); - - proxy = gvfs_dbus_progress_proxy_new_finish (res, &error); - if (proxy == NULL) - { - g_warning ("progress_proxy_new_cb: %s (%s, %d)\n", error->message, g_quark_to_string (error->domain), error->code); - g_error_free (error); - goto out; - } - - gvfs_dbus_progress_call_progress (proxy, - data->current_num_bytes, - data->total_num_bytes, - NULL, - (GAsyncReadyCallback) progress_cb, - NULL); - g_object_unref (proxy); - - out: - g_free (data); -} - -static void -progress_callback (goffset current_num_bytes, - goffset total_num_bytes, - gpointer user_data) -{ - GVfsJob *job = G_VFS_JOB (user_data); - GVfsJobDBus *dbus_job = G_VFS_JOB_DBUS (job); - GVfsJobPull *op_job = G_VFS_JOB_PULL (job); - ProgressCallbackData *data; - - g_debug ("progress_callback %" G_GOFFSET_FORMAT "/%" G_GOFFSET_FORMAT "\n", current_num_bytes, total_num_bytes); - - if (op_job->callback_obj_path == NULL) - return; - - data = g_new0 (ProgressCallbackData, 1); - data->current_num_bytes = current_num_bytes; - data->total_num_bytes = total_num_bytes; - - gvfs_dbus_progress_proxy_new (g_dbus_method_invocation_get_connection (dbus_job->invocation), - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, - g_dbus_method_invocation_get_sender (dbus_job->invocation), - op_job->callback_obj_path, - NULL, - progress_proxy_new_cb, - data); -} - static void run (GVfsJob *job) { GVfsJobPull *op_job = G_VFS_JOB_PULL (job); + GVfsJobProgress *progress_job = G_VFS_JOB_PROGRESS (job); GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); if (class->pull == NULL) @@ -206,33 +128,47 @@ run (GVfsJob *job) return; } + g_vfs_job_progress_construct_proxy (job); + class->pull (op_job->backend, op_job, op_job->source, op_job->local_path, op_job->flags, op_job->remove_source, - op_job->send_progress ? progress_callback : NULL, - op_job->send_progress ? job : NULL); + progress_job->send_progress ? g_vfs_job_progress_callback : NULL, + progress_job->send_progress ? job : NULL); + + if (progress_job->progress_proxy) + g_clear_object (&progress_job->progress_proxy); } static gboolean try (GVfsJob *job) { GVfsJobPull *op_job = G_VFS_JOB_PULL (job); + GVfsJobProgress *progress_job = G_VFS_JOB_PROGRESS (job); GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); + gboolean res; if (class->try_pull == NULL) return FALSE; - return class->try_pull (op_job->backend, - op_job, - op_job->source, - op_job->local_path, - op_job->flags, - op_job->remove_source, - op_job->send_progress ? progress_callback : NULL, - op_job->send_progress ? job : NULL); + g_vfs_job_progress_construct_proxy (job); + + res = class->try_pull (op_job->backend, + op_job, + op_job->source, + op_job->local_path, + op_job->flags, + op_job->remove_source, + progress_job->send_progress ? g_vfs_job_progress_callback : NULL, + progress_job->send_progress ? job : NULL); + + if (progress_job->progress_proxy) + g_clear_object (&progress_job->progress_proxy); + + return res; } /* Might be called on an i/o thread */ diff --git a/daemon/gvfsjobpull.h b/daemon/gvfsjobpull.h index eb739ea1..6ce7fa7e 100644 --- a/daemon/gvfsjobpull.h +++ b/daemon/gvfsjobpull.h @@ -27,6 +27,7 @@ #include <gvfsjob.h> #include <gvfsjobdbus.h> #include <gvfsbackend.h> +#include <gvfsjobprogress.h> G_BEGIN_DECLS @@ -41,20 +42,18 @@ typedef struct _GVfsJobPullClass GVfsJobPullClass; struct _GVfsJobPull { - GVfsJobDBus parent_instance; + GVfsJobProgress parent_instance; GVfsBackend *backend; char *source; char *local_path; GFileCopyFlags flags; - char *callback_obj_path; gboolean remove_source; - gboolean send_progress; }; struct _GVfsJobPullClass { - GVfsJobDBusClass parent_class; + GVfsJobProgressClass parent_class; }; GType g_vfs_job_pull_get_type (void) G_GNUC_CONST; diff --git a/daemon/gvfsjobpush.c b/daemon/gvfsjobpush.c index 824a339d..ffd3e979 100644 --- a/daemon/gvfsjobpush.c +++ b/daemon/gvfsjobpush.c @@ -33,7 +33,7 @@ #include "gvfsjobpush.h" #include "gvfsdbus.h" -G_DEFINE_TYPE (GVfsJobPush, g_vfs_job_push, G_VFS_TYPE_JOB_DBUS) +G_DEFINE_TYPE (GVfsJobPush, g_vfs_job_push, G_VFS_TYPE_JOB_PROGRESS) static void run (GVfsJob *job); static gboolean try (GVfsJob *job); @@ -50,7 +50,6 @@ g_vfs_job_push_finalize (GObject *object) g_free (job->local_path); g_free (job->destination); - g_free (job->callback_obj_path); if (G_OBJECT_CLASS (g_vfs_job_push_parent_class)->finalize) (*G_OBJECT_CLASS (g_vfs_job_push_parent_class)->finalize) (object); @@ -86,7 +85,8 @@ g_vfs_job_push_new_handle (GVfsDBusMount *object, GVfsBackend *backend) { GVfsJobPush *job; - + GVfsJobProgress *progress_job; + g_print ("called Push()\n"); if (g_vfs_backend_invocation_first_handler (object, invocation, backend)) @@ -96,16 +96,17 @@ g_vfs_job_push_new_handle (GVfsDBusMount *object, "object", object, "invocation", invocation, NULL); + progress_job = G_VFS_JOB_PROGRESS (job); job->destination = g_strdup (arg_path_data); job->local_path = g_strdup (arg_local_path); job->backend = backend; job->flags = arg_flags; - job->send_progress = arg_send_progress; + progress_job->send_progress = arg_send_progress; job->remove_source = arg_remove_source; g_debug ("Remove Source: %s\n", arg_remove_source ? "true" : "false"); if (strcmp (arg_progress_obj_path, "/org/gtk/vfs/void") != 0) - job->callback_obj_path = g_strdup (arg_progress_obj_path); + progress_job->callback_obj_path = g_strdup (arg_progress_obj_path); g_vfs_job_source_new_job (G_VFS_JOB_SOURCE (backend), G_VFS_JOB (job)); g_object_unref (job); @@ -113,90 +114,11 @@ g_vfs_job_push_new_handle (GVfsDBusMount *object, return TRUE; } -typedef struct { - goffset current_num_bytes; - goffset total_num_bytes; -} ProgressCallbackData; - -static void -progress_cb (GVfsDBusProgress *proxy, - GAsyncResult *res, - gpointer user_data) -{ - GError *error = NULL; - - g_print ("progress_cb\n"); - - if (! gvfs_dbus_progress_call_progress_finish (proxy, res, &error)) - { - g_warning ("progress_cb: %s (%s, %d)\n", error->message, g_quark_to_string (error->domain), error->code); - g_error_free (error); - } -} - -static void -progress_proxy_new_cb (GObject *source_object, - GAsyncResult *res, - gpointer user_data) -{ - ProgressCallbackData *data = user_data; - GVfsDBusProgress *proxy; - GError *error = NULL; - - g_print ("progress_proxy_new_cb\n"); - - proxy = gvfs_dbus_progress_proxy_new_finish (res, &error); - if (proxy == NULL) - { - g_warning ("progress_proxy_new_cb: %s (%s, %d)\n", error->message, g_quark_to_string (error->domain), error->code); - g_error_free (error); - goto out; - } - - gvfs_dbus_progress_call_progress (proxy, - data->current_num_bytes, - data->total_num_bytes, - NULL, - (GAsyncReadyCallback) progress_cb, - NULL); - g_object_unref (proxy); - - out: - g_free (data); -} - -static void -progress_callback (goffset current_num_bytes, - goffset total_num_bytes, - gpointer user_data) -{ - GVfsJob *job = G_VFS_JOB (user_data); - GVfsJobDBus *dbus_job = G_VFS_JOB_DBUS (job); - GVfsJobPush *op_job = G_VFS_JOB_PUSH (job); - ProgressCallbackData *data; - - g_debug ("progress_callback %" G_GOFFSET_FORMAT "/%" G_GOFFSET_FORMAT "\n", current_num_bytes, total_num_bytes); - - if (op_job->callback_obj_path == NULL) - return; - - data = g_new0 (ProgressCallbackData, 1); - data->current_num_bytes = current_num_bytes; - data->total_num_bytes = total_num_bytes; - - gvfs_dbus_progress_proxy_new (g_dbus_method_invocation_get_connection (dbus_job->invocation), - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, - g_dbus_method_invocation_get_sender (dbus_job->invocation), - op_job->callback_obj_path, - NULL, - progress_proxy_new_cb, - data); -} - static void run (GVfsJob *job) { GVfsJobPush *op_job = G_VFS_JOB_PUSH (job); + GVfsJobProgress *progress_job = G_VFS_JOB_PROGRESS (job); GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); if (class->push == NULL) @@ -206,33 +128,47 @@ run (GVfsJob *job) return; } + g_vfs_job_progress_construct_proxy (job); + class->push (op_job->backend, op_job, op_job->destination, op_job->local_path, op_job->flags, op_job->remove_source, - op_job->send_progress ? progress_callback : NULL, - op_job->send_progress ? job : NULL); + progress_job->send_progress ? g_vfs_job_progress_callback : NULL, + progress_job->send_progress ? job : NULL); + + if (progress_job->progress_proxy) + g_clear_object (&progress_job->progress_proxy); } static gboolean try (GVfsJob *job) { GVfsJobPush *op_job = G_VFS_JOB_PUSH (job); + GVfsJobProgress *progress_job = G_VFS_JOB_PROGRESS (job); GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend); + gboolean res; if (class->try_push == NULL) return FALSE; - return class->try_push (op_job->backend, - op_job, - op_job->destination, - op_job->local_path, - op_job->flags, - op_job->remove_source, - op_job->send_progress ? progress_callback : NULL, - op_job->send_progress ? job : NULL); + g_vfs_job_progress_construct_proxy (job); + + res = class->try_push (op_job->backend, + op_job, + op_job->destination, + op_job->local_path, + op_job->flags, + op_job->remove_source, + progress_job->send_progress ? g_vfs_job_progress_callback : NULL, + progress_job->send_progress ? job : NULL); + + if (progress_job->progress_proxy) + g_clear_object (&progress_job->progress_proxy); + + return res; } /* Might be called on an i/o thread */ diff --git a/daemon/gvfsjobpush.h b/daemon/gvfsjobpush.h index ae869b00..c710790d 100644 --- a/daemon/gvfsjobpush.h +++ b/daemon/gvfsjobpush.h @@ -27,6 +27,7 @@ #include <gvfsjob.h> #include <gvfsjobdbus.h> #include <gvfsbackend.h> +#include <gvfsjobprogress.h> G_BEGIN_DECLS @@ -41,20 +42,18 @@ typedef struct _GVfsJobPushClass GVfsJobPushClass; struct _GVfsJobPush { - GVfsJobDBus parent_instance; + GVfsJobProgress parent_instance; GVfsBackend *backend; char *destination; char *local_path; GFileCopyFlags flags; - char *callback_obj_path; - gboolean send_progress; gboolean remove_source; }; struct _GVfsJobPushClass { - GVfsJobDBusClass parent_class; + GVfsJobProgressClass parent_class; }; GType g_vfs_job_push_get_type (void) G_GNUC_CONST; |