[gvfs/gdbus-core] gdbus: Make copy progress work



commit 722ebaf0ab949ca5b844a387dc684b4e3185db75
Author: Tomas Bzatek <tbzatek redhat com>
Date:   Fri Jun 29 16:26:13 2012 +0200

    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.

 client/gdaemonfile.c     |  138 +++++++++++++++++++++++++++++----------------
 daemon/Makefile.am       |    1 +
 daemon/gvfsbackendsftp.c |    3 +-
 daemon/gvfsjobcopy.c     |  123 ++++++++++-------------------------------
 daemon/gvfsjobcopy.h     |    7 +-
 daemon/gvfsjobmove.c     |  122 ++++++++++------------------------------
 daemon/gvfsjobmove.h     |    7 +-
 daemon/gvfsjobpull.c     |  126 ++++++++++-------------------------------
 daemon/gvfsjobpull.h     |    7 +-
 daemon/gvfsjobpush.c     |  126 ++++++++++-------------------------------
 daemon/gvfsjobpush.h     |    7 +-
 11 files changed, 226 insertions(+), 441 deletions(-)
---
diff --git a/client/gdaemonfile.c b/client/gdaemonfile.c
index 7e6895c..64a0148 100644
--- a/client/gdaemonfile.c
+++ b/client/gdaemonfile.c
@@ -2788,20 +2788,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);
@@ -2809,6 +2812,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,
@@ -2820,7 +2834,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;
@@ -2864,14 +2878,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)
     {
@@ -2905,69 +2916,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 55cf029..7c13e8c 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -143,6 +143,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 7dd90eb..af4cec5 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 64ec24c..bf563c1 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 cb45ae0..179c903 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 c211a95..4e8aa46 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 e561a3e..b4b9653 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 4a658de..52e6295 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 b070ee6..124146a 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 4fc3733..335ed90 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 8eba812..0ff9608 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;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]