summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@redhat.com>2012-06-15 17:24:42 +0200
committerTomas Bzatek <tbzatek@redhat.com>2012-07-31 11:59:37 +0200
commit89a881c5bf8fcbaf027e276a302aefc11f8fca34 (patch)
tree3b6fbd0f38d0e657d1988b4139f84148097fd4ce /client
parent36635d44502b5c4e8f7e1341ad9ec912bb822e0d (diff)
downloadgvfs-89a881c5bf8fcbaf027e276a302aefc11f8fca34.tar.gz
gdbus: Make cancellation work
This mimics the old behaviour and works for sync and async. Requires new glib for g_dbus_connection_get_last_serial().
Diffstat (limited to 'client')
-rw-r--r--client/gdaemonfile.c194
-rw-r--r--client/gdaemonmount.c3
-rw-r--r--client/gvfsdaemondbus.c125
-rw-r--r--client/gvfsdaemondbus.h6
-rw-r--r--client/gvfsiconloadable.c13
5 files changed, 319 insertions, 22 deletions
diff --git a/client/gdaemonfile.c b/client/gdaemonfile.c
index 861e7416..b60e6725 100644
--- a/client/gdaemonfile.c
+++ b/client/gdaemonfile.c
@@ -690,6 +690,7 @@ g_daemon_file_enumerate_children (GFile *file,
char *uri;
GVfsDBusMount *proxy;
gboolean res;
+ GError *local_error = NULL;
g_print ("g_daemon_file_enumerate_children\n");
@@ -709,9 +710,16 @@ g_daemon_file_enumerate_children (GFile *file,
flags,
uri,
cancellable,
- error);
+ &local_error);
g_print ("g_daemon_file_enumerate_children: done, res = %d\n", res);
+
+ if (! res)
+ {
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ _g_dbus_send_cancelled_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (proxy)));
+ g_propagate_error (error, local_error);
+ }
g_free (path);
g_free (uri);
@@ -808,6 +816,7 @@ g_daemon_file_query_info (GFile *file,
GVfsDBusMount *proxy;
GVariant *iter_info;
gboolean res;
+ GError *local_error = NULL;
g_print ("g_daemon_file_query_info\n");
@@ -825,10 +834,17 @@ g_daemon_file_query_info (GFile *file,
uri,
&iter_info,
cancellable,
- error);
+ &local_error);
g_print ("g_daemon_file_query_info: done, res = %d\n", res);
+ if (! res)
+ {
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ _g_dbus_send_cancelled_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (proxy)));
+ g_propagate_error (error, local_error);
+ }
+
g_free (path);
g_free (uri);
g_object_unref (proxy);
@@ -853,6 +869,7 @@ typedef struct {
int io_priority;
GSimpleAsyncResult *result;
GCancellable *cancellable;
+ gulong cancelled_tag;
} AsyncCallQueryInfo;
static void
@@ -906,6 +923,7 @@ query_info_async_cb (GVfsDBusMount *proxy,
out:
_g_simple_async_result_complete_with_cancellable (orig_result, data->cancellable);
+ _g_dbus_async_unsubscribe_cancellable (data->cancellable, data->cancelled_tag);
data->result = NULL;
g_object_unref (orig_result); /* trigger async_proxy_create_free() */
}
@@ -937,6 +955,7 @@ query_info_async_get_proxy_cb (GVfsDBusMount *proxy,
cancellable,
(GAsyncReadyCallback) query_info_async_cb,
data);
+ data->cancelled_tag = _g_dbus_async_subscribe_cancellable (connection, cancellable);
g_free (uri);
}
@@ -994,6 +1013,7 @@ typedef struct {
GFileCreateFlags flags;
GSimpleAsyncResult *result;
GCancellable *cancellable;
+ gulong cancelled_tag;
} AsyncCallFileReadWrite;
static void
@@ -1048,6 +1068,7 @@ read_async_cb (GVfsDBusMount *proxy,
out:
_g_simple_async_result_complete_with_cancellable (orig_result, data->cancellable);
+ _g_dbus_async_unsubscribe_cancellable (data->cancellable, data->cancelled_tag);
data->result = NULL;
g_object_unref (orig_result); /* trigger async_proxy_create_free() */
}
@@ -1078,6 +1099,7 @@ file_read_async_get_proxy_cb (GVfsDBusMount *proxy,
cancellable,
(GAsyncReadyCallback) read_async_cb,
data);
+ data->cancelled_tag = _g_dbus_async_subscribe_cancellable (connection, cancellable);
}
static void
@@ -1132,6 +1154,7 @@ g_daemon_file_read (GFile *file,
int fd;
guint fd_id;
guint32 pid;
+ GError *local_error = NULL;
g_print ("g_daemon_file_read\n");
@@ -1149,10 +1172,17 @@ g_daemon_file_read (GFile *file,
&can_seek,
&fd_list,
cancellable,
- error);
+ &local_error);
g_print ("g_daemon_file_read: done, res = %d\n", res);
-
+
+ if (! res)
+ {
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ _g_dbus_send_cancelled_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (proxy)));
+ g_propagate_error (error, local_error);
+ }
+
g_free (path);
g_object_unref (proxy);
@@ -1190,6 +1220,7 @@ file_open_write (GFile *file,
guint32 fd_id;
guint32 pid;
guint64 initial_offset;
+ GError *local_error = NULL;
pid = get_pid_for_file (file);
@@ -1213,10 +1244,17 @@ file_open_write (GFile *file,
&initial_offset,
&fd_list,
cancellable,
- error);
+ &local_error);
g_print ("file_open_write: done, res = %d\n", res);
-
+
+ if (! res)
+ {
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ _g_dbus_send_cancelled_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (proxy)));
+ g_propagate_error (error, local_error);
+ }
+
g_free (path);
g_object_unref (proxy);
@@ -1277,6 +1315,7 @@ typedef struct {
GCancellable *cancellable;
guint32 flags;
GMountOperation *mount_operation;
+ gulong cancelled_tag;
} AsyncMountOp;
static void
@@ -1383,6 +1422,7 @@ mount_mountable_async_cb (GVfsDBusMount *proxy,
out:
_g_simple_async_result_complete_with_cancellable (orig_result, data->cancellable);
+ _g_dbus_async_unsubscribe_cancellable (data->cancellable, data->cancelled_tag);
g_object_unref (orig_result); /* trigger async_proxy_create_free() */
}
@@ -1416,6 +1456,7 @@ mount_mountable_got_proxy_cb (GVfsDBusMount *proxy,
cancellable,
(GAsyncReadyCallback) mount_mountable_async_cb,
data);
+ data->cancelled_tag = _g_dbus_async_subscribe_cancellable (connection, cancellable);
g_object_unref (mount_source);
}
@@ -1476,6 +1517,7 @@ start_mountable_async_cb (GVfsDBusMount *proxy,
g_simple_async_result_take_error (orig_result, error);
_g_simple_async_result_complete_with_cancellable (orig_result, data->cancellable);
+ _g_dbus_async_unsubscribe_cancellable (data->cancellable, data->cancelled_tag);
data->result = NULL;
g_object_unref (orig_result); /* trigger async_proxy_create_free() */
}
@@ -1510,6 +1552,7 @@ start_mountable_got_proxy_cb (GVfsDBusMount *proxy,
cancellable,
(GAsyncReadyCallback) start_mountable_async_cb,
data);
+ data->cancelled_tag = _g_dbus_async_subscribe_cancellable (connection, cancellable);
g_object_unref (mount_source);
}
@@ -1563,6 +1606,7 @@ stop_mountable_async_cb (GVfsDBusMount *proxy,
g_simple_async_result_take_error (orig_result, error);
_g_simple_async_result_complete_with_cancellable (orig_result, data->cancellable);
+ _g_dbus_async_unsubscribe_cancellable (data->cancellable, data->cancelled_tag);
data->result = NULL;
g_object_unref (orig_result); /* trigger async_proxy_create_free() */
}
@@ -1598,6 +1642,7 @@ stop_mountable_got_proxy_cb (GVfsDBusMount *proxy,
cancellable,
(GAsyncReadyCallback) stop_mountable_async_cb,
data);
+ data->cancelled_tag = _g_dbus_async_subscribe_cancellable (connection, cancellable);
g_object_unref (mount_source);
}
@@ -1651,6 +1696,7 @@ eject_mountable_async_cb (GVfsDBusMount *proxy,
g_simple_async_result_take_error (orig_result, error);
_g_simple_async_result_complete_with_cancellable (orig_result, data->cancellable);
+ _g_dbus_async_unsubscribe_cancellable (data->cancellable, data->cancelled_tag);
data->result = NULL;
g_object_unref (orig_result); /* trigger async_proxy_create_free() */
}
@@ -1686,6 +1732,7 @@ eject_mountable_got_proxy_cb (GVfsDBusMount *proxy,
cancellable,
(GAsyncReadyCallback) eject_mountable_async_cb,
data);
+ data->cancelled_tag = _g_dbus_async_subscribe_cancellable (connection, cancellable);
g_object_unref (mount_source);
}
@@ -1757,6 +1804,7 @@ unmount_mountable_async_cb (GVfsDBusMount *proxy,
g_simple_async_result_take_error (orig_result, error);
_g_simple_async_result_complete_with_cancellable (orig_result, data->cancellable);
+ _g_dbus_async_unsubscribe_cancellable (data->cancellable, data->cancelled_tag);
data->result = NULL;
g_object_unref (orig_result); /* trigger async_proxy_create_free() */
}
@@ -1792,6 +1840,7 @@ unmount_mountable_got_proxy_cb (GVfsDBusMount *proxy,
cancellable,
(GAsyncReadyCallback) unmount_mountable_async_cb,
data);
+ data->cancelled_tag = _g_dbus_async_subscribe_cancellable (connection, cancellable);
g_object_unref (mount_source);
}
@@ -1845,6 +1894,7 @@ poll_mountable_async_cb (GVfsDBusMount *proxy,
g_simple_async_result_take_error (orig_result, error);
_g_simple_async_result_complete_with_cancellable (orig_result, data->cancellable);
+ _g_dbus_async_unsubscribe_cancellable (data->cancellable, data->cancelled_tag);
data->result = NULL;
g_object_unref (orig_result); /* trigger async_proxy_create_free() */
}
@@ -1870,6 +1920,7 @@ poll_mountable_got_proxy_cb (GVfsDBusMount *proxy,
cancellable,
(GAsyncReadyCallback) poll_mountable_async_cb,
data);
+ data->cancelled_tag = _g_dbus_async_subscribe_cancellable (connection, cancellable);
}
static void
@@ -2074,6 +2125,7 @@ g_daemon_file_query_filesystem_info (GFile *file,
char *path;
gboolean res;
GVariant *iter_info;
+ GError *local_error = NULL;
g_print ("g_daemon_file_query_filesystem_info\n");
@@ -2087,10 +2139,17 @@ g_daemon_file_query_filesystem_info (GFile *file,
attributes ? attributes : "",
&iter_info,
cancellable,
- error);
+ &local_error);
g_print ("g_daemon_file_query_filesystem_info: done, res = %d\n", res);
+ if (! res)
+ {
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ _g_dbus_send_cancelled_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (proxy)));
+ g_propagate_error (error, local_error);
+ }
+
g_free (path);
g_object_unref (proxy);
@@ -2111,6 +2170,7 @@ typedef struct {
int io_priority;
GSimpleAsyncResult *result;
GCancellable *cancellable;
+ gulong cancelled_tag;
} AsyncCallQueryFsInfo;
static void
@@ -2159,6 +2219,7 @@ query_fs_info_async_cb (GVfsDBusMount *proxy,
out:
_g_simple_async_result_complete_with_cancellable (orig_result, data->cancellable);
+ _g_dbus_async_unsubscribe_cancellable (data->cancellable, data->cancelled_tag);
data->result = NULL;
g_object_unref (orig_result); /* trigger async_proxy_create_free() */
}
@@ -2188,6 +2249,7 @@ query_info_fs_async_get_proxy_cb (GVfsDBusMount *proxy,
cancellable,
(GAsyncReadyCallback) query_fs_info_async_cb,
data);
+ data->cancelled_tag = _g_dbus_async_subscribe_cancellable (connection, cancellable);
g_free (uri);
}
@@ -2323,6 +2385,7 @@ g_daemon_file_set_display_name (GFile *file,
GVfsDBusMount *proxy;
char *path;
gboolean res;
+ GError *local_error = NULL;
daemon_file = G_DAEMON_FILE (file);
mount_info = NULL;
@@ -2337,9 +2400,16 @@ g_daemon_file_set_display_name (GFile *file,
display_name ? display_name : "",
&new_path,
cancellable,
- error);
+ &local_error);
g_print ("g_daemon_file_set_display_name: done, res = %d\n", res);
+ if (! res)
+ {
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ _g_dbus_send_cancelled_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (proxy)));
+ g_propagate_error (error, local_error);
+ }
+
g_free (path);
g_object_unref (proxy);
@@ -2363,6 +2433,7 @@ g_daemon_file_delete (GFile *file,
GVfsDBusMount *proxy;
char *path;
gboolean res;
+ GError *local_error = NULL;
g_print ("g_daemon_file_delete\n");
@@ -2373,9 +2444,16 @@ g_daemon_file_delete (GFile *file,
res = gvfs_dbus_mount_call_delete_sync (proxy,
path,
cancellable,
- error);
+ &local_error);
g_print ("g_daemon_file_delete: done, res = %d\n", res);
+ if (! res)
+ {
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ _g_dbus_send_cancelled_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (proxy)));
+ g_propagate_error (error, local_error);
+ }
+
g_free (path);
g_object_unref (proxy);
@@ -2390,6 +2468,7 @@ g_daemon_file_trash (GFile *file,
GVfsDBusMount *proxy;
char *path;
gboolean res;
+ GError *local_error = NULL;
g_print ("g_daemon_file_trash\n");
@@ -2400,9 +2479,16 @@ g_daemon_file_trash (GFile *file,
res = gvfs_dbus_mount_call_trash_sync (proxy,
path,
cancellable,
- error);
+ &local_error);
g_print ("g_daemon_file_trash: done, res = %d\n", res);
+ if (! res)
+ {
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ _g_dbus_send_cancelled_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (proxy)));
+ g_propagate_error (error, local_error);
+ }
+
g_free (path);
g_object_unref (proxy);
@@ -2417,6 +2503,7 @@ g_daemon_file_make_directory (GFile *file,
GVfsDBusMount *proxy;
char *path;
gboolean res;
+ GError *local_error = NULL;
g_print ("g_daemon_file_make_directory\n");
@@ -2427,9 +2514,16 @@ g_daemon_file_make_directory (GFile *file,
res = gvfs_dbus_mount_call_make_directory_sync (proxy,
path,
cancellable,
- error);
+ &local_error);
g_print ("g_daemon_file_make_directory: done, res = %d\n", res);
+ if (! res)
+ {
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ _g_dbus_send_cancelled_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (proxy)));
+ g_propagate_error (error, local_error);
+ }
+
g_free (path);
g_object_unref (proxy);
@@ -2445,6 +2539,7 @@ g_daemon_file_make_symbolic_link (GFile *file,
GVfsDBusMount *proxy;
char *path;
gboolean res;
+ GError *local_error = NULL;
g_print ("g_daemon_file_make_symbolic_link\n");
@@ -2456,9 +2551,16 @@ g_daemon_file_make_symbolic_link (GFile *file,
path,
symlink_value ? symlink_value : "",
cancellable,
- error);
+ &local_error);
g_print ("g_daemon_file_make_symbolic_link: done, res = %d\n", res);
+ if (! res)
+ {
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ _g_dbus_send_cancelled_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (proxy)));
+ g_propagate_error (error, local_error);
+ }
+
g_free (path);
g_object_unref (proxy);
@@ -2475,6 +2577,7 @@ g_daemon_file_query_settable_attributes (GFile *file,
gboolean res;
GVariant *iter_list;
GFileAttributeInfoList *list;
+ GError *local_error = NULL;
g_print ("g_daemon_file_query_settable_attributes\n");
@@ -2487,9 +2590,16 @@ g_daemon_file_query_settable_attributes (GFile *file,
path,
&iter_list,
cancellable,
- error);
+ &local_error);
g_print ("g_daemon_file_query_settable_attributes: done, res = %d\n", res);
+ if (! res)
+ {
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ _g_dbus_send_cancelled_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (proxy)));
+ g_propagate_error (error, local_error);
+ }
+
g_free (path);
g_object_unref (proxy);
@@ -2512,6 +2622,7 @@ g_daemon_file_query_writable_namespaces (GFile *file,
gboolean res;
GVariant *iter_list;
GFileAttributeInfoList *list;
+ GError *local_error = NULL;
g_print ("g_daemon_file_query_writable_namespaces\n");
@@ -2524,9 +2635,16 @@ g_daemon_file_query_writable_namespaces (GFile *file,
path,
&iter_list,
cancellable,
- error);
+ &local_error);
g_print ("g_daemon_file_query_writable_namespaces: done, res = %d\n", res);
+ if (! res)
+ {
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ _g_dbus_send_cancelled_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (proxy)));
+ g_propagate_error (error, local_error);
+ }
+
g_free (path);
g_object_unref (proxy);
@@ -2648,19 +2766,24 @@ g_daemon_file_set_attribute (GFile *file,
g_print ("g_daemon_file_set_attribute: done, res = %d\n", res);
g_free (path);
- g_object_unref (proxy);
if (! res)
{
+ if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ _g_dbus_send_cancelled_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (proxy)));
+ else
if (g_error_matches (my_error, G_VFS_ERROR, G_VFS_ERROR_RETRY))
{
g_error_free (my_error);
+ g_object_unref (proxy);
goto retry;
}
g_propagate_error (error, my_error);
return FALSE;
}
+ g_object_unref (proxy);
+
return TRUE;
}
@@ -2844,19 +2967,24 @@ retry:
g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (progress_skeleton));
g_object_unref (progress_skeleton);
}
- if (proxy)
- g_object_unref (proxy);
if (! res)
{
+ if (proxy && g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ _g_dbus_send_cancelled_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (proxy)));
+ else
if (g_error_matches (my_error, G_VFS_ERROR, G_VFS_ERROR_RETRY))
{
g_error_free (my_error);
+ g_object_unref (proxy);
goto retry;
}
g_propagate_error (error, my_error);
}
+ if (proxy)
+ g_object_unref (proxy);
+
g_free (local_path);
g_free (obj_path);
@@ -2921,6 +3049,7 @@ g_daemon_file_monitor_dir (GFile* file,
char *path;
char *obj_path;
gboolean res;
+ GError *local_error = NULL;
g_print ("g_daemon_file_monitor_dir\n");
@@ -2938,9 +3067,16 @@ g_daemon_file_monitor_dir (GFile* file,
flags,
&obj_path,
cancellable,
- error);
+ &local_error);
g_print ("g_daemon_file_monitor_dir: done, res = %d\n", res);
-
+
+ if (! res)
+ {
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ _g_dbus_send_cancelled_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (proxy)));
+ g_propagate_error (error, local_error);
+ }
+
g_free (path);
g_object_unref (proxy);
@@ -2969,6 +3105,7 @@ g_daemon_file_monitor_file (GFile* file,
char *path;
char *obj_path;
gboolean res;
+ GError *local_error = NULL;
g_print ("g_daemon_file_monitor_file\n");
@@ -2986,9 +3123,16 @@ g_daemon_file_monitor_file (GFile* file,
flags,
&obj_path,
cancellable,
- error);
+ &local_error);
g_print ("g_daemon_file_monitor_file: done, res = %d\n", res);
-
+
+ if (! res)
+ {
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ _g_dbus_send_cancelled_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (proxy)));
+ g_propagate_error (error, local_error);
+ }
+
g_free (path);
g_object_unref (proxy);
@@ -3046,6 +3190,7 @@ file_open_write_async_cb (GVfsDBusMount *proxy,
out:
_g_simple_async_result_complete_with_cancellable (orig_result, data->cancellable);
+ _g_dbus_async_unsubscribe_cancellable (data->cancellable, data->cancelled_tag);
data->result = NULL;
g_object_unref (orig_result); /* trigger async_proxy_create_free() */
}
@@ -3080,6 +3225,7 @@ file_open_write_async_get_proxy_cb (GVfsDBusMount *proxy,
cancellable,
(GAsyncReadyCallback) file_open_write_async_cb,
data);
+ data->cancelled_tag = _g_dbus_async_subscribe_cancellable (connection, cancellable);
}
static void
@@ -3182,6 +3328,7 @@ typedef struct {
GSimpleAsyncResult *result;
GCancellable *cancellable;
GDaemonFileEnumerator *enumerator;
+ gulong cancelled_tag;
} AsyncCallEnumerate;
static void
@@ -3225,6 +3372,7 @@ enumerate_children_async_cb (GVfsDBusMount *proxy,
out:
_g_simple_async_result_complete_with_cancellable (orig_result, data->cancellable);
+ _g_dbus_async_unsubscribe_cancellable (data->cancellable, data->cancelled_tag);
data->result = NULL;
g_object_unref (orig_result); /* trigger async_proxy_create_free() */
}
@@ -3259,6 +3407,7 @@ enumerate_children_async_get_proxy_cb (GVfsDBusMount *proxy,
cancellable,
(GAsyncReadyCallback) enumerate_children_async_cb,
data);
+ data->cancelled_tag = _g_dbus_async_subscribe_cancellable (connection, cancellable);
g_free (uri);
g_free (obj_path);
@@ -3454,6 +3603,7 @@ typedef struct {
GMountInfo *mount_info;
GSimpleAsyncResult *result;
GCancellable *cancellable;
+ gulong cancelled_tag;
} AsyncCallSetDisplayName;
static void
@@ -3500,6 +3650,7 @@ set_display_name_async_cb (GVfsDBusMount *proxy,
out:
_g_simple_async_result_complete_with_cancellable (orig_result, data->cancellable);
+ _g_dbus_async_unsubscribe_cancellable (data->cancellable, data->cancelled_tag);
data->result = NULL;
g_object_unref (orig_result); /* trigger async_proxy_create_free() */
}
@@ -3527,6 +3678,7 @@ set_display_name_async_get_proxy_cb (GVfsDBusMount *proxy,
cancellable,
(GAsyncReadyCallback) set_display_name_async_cb,
data);
+ data->cancelled_tag = _g_dbus_async_subscribe_cancellable (connection, cancellable);
}
static void
diff --git a/client/gdaemonmount.c b/client/gdaemonmount.c
index 1104f9b6..fa29e07b 100644
--- a/client/gdaemonmount.c
+++ b/client/gdaemonmount.c
@@ -182,6 +182,7 @@ typedef struct {
GMountUnmountFlags flags;
GDBusConnection *connection;
GVfsDBusMount *proxy;
+ gulong cancelled_tag;
} AsyncProxyCreate;
static void
@@ -218,6 +219,7 @@ unmount_reply (GVfsDBusMount *proxy,
}
_g_simple_async_result_complete_with_cancellable (data->result, data->cancellable);
+ _g_dbus_async_unsubscribe_cancellable (data->cancellable, data->cancelled_tag);
async_proxy_create_free (data);
}
@@ -253,6 +255,7 @@ async_proxy_new_cb (GObject *source_object,
data->cancellable,
(GAsyncReadyCallback) unmount_reply,
data);
+ data->cancelled_tag = _g_dbus_async_subscribe_cancellable (data->connection, data->cancellable);
g_object_unref (mount_source);
}
diff --git a/client/gvfsdaemondbus.c b/client/gvfsdaemondbus.c
index 790d6ebb..3e09ea7b 100644
--- a/client/gvfsdaemondbus.c
+++ b/client/gvfsdaemondbus.c
@@ -492,6 +492,131 @@ _g_dbus_connection_get_for_async (const char *dbus_id,
}
}
+
+typedef struct {
+ GDBusConnection *connection;
+ guint32 serial;
+} AsyncCallCancelData;
+
+static void
+async_call_cancel_data_free (gpointer _data)
+{
+ AsyncCallCancelData *data = _data;
+
+ g_object_unref (data->connection);
+ g_free (data);
+}
+
+static void
+cancelled_got_proxy (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ guint32 serial = GPOINTER_TO_UINT (user_data);
+ GVfsDBusDaemon *proxy;
+ GError *error = NULL;
+
+ proxy = gvfs_dbus_daemon_proxy_new_finish (res, &error);
+ if (! proxy)
+ {
+ g_printerr ("Failed to construct daemon proxy for cancellation: %s (%s, %d)\n",
+ error->message, g_quark_to_string (error->domain), error->code);
+ g_error_free (error);
+ return;
+ }
+
+ gvfs_dbus_daemon_call_cancel (proxy,
+ serial,
+ NULL,
+ NULL, /* we don't need any reply */
+ NULL);
+ g_object_unref (proxy);
+}
+
+/* Might be called on another thread */
+static void
+async_call_cancelled_cb (GCancellable *cancellable,
+ gpointer _data)
+{
+ AsyncCallCancelData *data = _data;
+
+ /* TODO: use shared daemon proxy on private connection if possible */
+ gvfs_dbus_daemon_proxy_new (data->connection,
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ NULL,
+ G_VFS_DBUS_DAEMON_PATH,
+ NULL,
+ cancelled_got_proxy,
+ GUINT_TO_POINTER (data->serial)); /* not passing "data" in as long it may not exist anymore between async calls */
+}
+
+gulong
+_g_dbus_async_subscribe_cancellable (GDBusConnection *connection, GCancellable *cancellable)
+{
+ AsyncCallCancelData *cancel_data;
+ gulong cancelled_tag = 0;
+
+ if (cancellable)
+ {
+ cancel_data = g_new0 (AsyncCallCancelData, 1);
+ cancel_data->connection = g_object_ref (connection);
+ /* make sure we get the serial *after* the message has been sent, otherwise
+ * it will be 0
+ */
+ cancel_data->serial = g_dbus_connection_get_last_serial (connection);
+ cancelled_tag =
+ g_signal_connect_data (cancellable, "cancelled",
+ (GCallback)async_call_cancelled_cb,
+ cancel_data,
+ (GClosureNotify)async_call_cancel_data_free,
+ 0);
+ }
+
+ return cancelled_tag;
+}
+
+void
+_g_dbus_async_unsubscribe_cancellable (GCancellable *cancellable, gulong cancelled_tag)
+{
+ if (cancelled_tag)
+ {
+ g_assert (cancellable != NULL);
+ g_signal_handler_disconnect (cancellable, cancelled_tag);
+ }
+}
+
+void
+ _g_dbus_send_cancelled_sync (GDBusConnection *connection)
+{
+ guint32 serial;
+ GVfsDBusDaemon *proxy;
+ GError *error = NULL;
+
+ serial = g_dbus_connection_get_last_serial (connection);
+
+ proxy = gvfs_dbus_daemon_proxy_new_sync (connection,
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ NULL,
+ G_VFS_DBUS_DAEMON_PATH,
+ NULL,
+ &error);
+ if (! proxy)
+ {
+ g_printerr ("Failed to construct daemon proxy for cancellation: %s (%s, %d)\n",
+ error->message, g_quark_to_string (error->domain), error->code);
+ g_error_free (error);
+ return;
+ }
+
+ gvfs_dbus_daemon_call_cancel (proxy,
+ serial,
+ NULL,
+ NULL, /* we don't need any reply */
+ NULL);
+ g_object_unref (proxy);
+}
+
+
/*************************************************************************
* get per-thread synchronous dbus connections *
*************************************************************************/
diff --git a/client/gvfsdaemondbus.h b/client/gvfsdaemondbus.h
index d1cd6660..eedf1d8b 100644
--- a/client/gvfsdaemondbus.h
+++ b/client/gvfsdaemondbus.h
@@ -64,6 +64,12 @@ void _g_simple_async_result_complete_with_cancellable
(GSimpleAsyncResult *result,
GCancellable *cancellable);
+gulong _g_dbus_async_subscribe_cancellable (GDBusConnection *connection,
+ GCancellable *cancellable);
+void _g_dbus_async_unsubscribe_cancellable (GCancellable *cancellable,
+ gulong cancelled_tag);
+void _g_dbus_send_cancelled_sync (GDBusConnection *connection);
+
G_END_DECLS
#endif /* __G_VFS_DAEMON_DBUS_H__ */
diff --git a/client/gvfsiconloadable.c b/client/gvfsiconloadable.c
index 049eac8b..b639adfb 100644
--- a/client/gvfsiconloadable.c
+++ b/client/gvfsiconloadable.c
@@ -92,6 +92,7 @@ g_vfs_icon_load (GLoadableIcon *icon,
GUnixFDList *fd_list;
int fd;
guint32 fd_id;
+ GError *local_error = NULL;
g_print ("gvfsiconloadable.c: g_vfs_icon_load\n");
@@ -106,10 +107,17 @@ g_vfs_icon_load (GLoadableIcon *icon,
&can_seek,
&fd_list,
cancellable,
- error);
+ &local_error);
g_print ("gvfsiconloadable.c: g_vfs_icon_load: done, res = %d\n", res);
+ if (! res)
+ {
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ _g_dbus_send_cancelled_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (proxy)));
+ g_propagate_error (error, local_error);
+ }
+
g_object_unref (proxy);
if (! res)
@@ -143,6 +151,7 @@ typedef struct {
GCancellable *cancellable;
CreateProxyAsyncCallback callback;
gpointer callback_data;
+ gulong cancelled_tag;
} AsyncPathCall;
@@ -308,6 +317,7 @@ open_icon_read_cb (GVfsDBusMount *proxy,
out:
_g_simple_async_result_complete_with_cancellable (data->result, data->cancellable);
+ _g_dbus_async_unsubscribe_cancellable (data->cancellable, data->cancelled_tag);
async_path_call_free (data);
}
@@ -327,6 +337,7 @@ load_async_cb (GVfsDBusMount *proxy,
cancellable,
(GAsyncReadyCallback) open_icon_read_cb,
callback_data);
+ data->cancelled_tag = _g_dbus_async_subscribe_cancellable (data->connection, cancellable);
}
static void