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



commit 918cebfd9b96b22179b4685d94e72b6c97090eb3
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 b60e672..5ffd1a7 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 b6e999c..bc9da0a 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 08c7c2a..672f8d4 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 9be8472..6320ca0 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 322d2c7..bb575c5 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 bac5618..c74f074 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 b1eec94..7b18900 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 3dda992..843d6f6 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 eb739ea..6ce7fa7 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 824a339..ffd3e97 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 ae869b0..c710790 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]