diff options
author | Tomas Bzatek <tbzatek@redhat.com> | 2012-06-15 17:24:42 +0200 |
---|---|---|
committer | Tomas Bzatek <tbzatek@redhat.com> | 2012-07-31 11:59:37 +0200 |
commit | 89a881c5bf8fcbaf027e276a302aefc11f8fca34 (patch) | |
tree | 3b6fbd0f38d0e657d1988b4139f84148097fd4ce /client | |
parent | 36635d44502b5c4e8f7e1341ad9ec912bb822e0d (diff) | |
download | gvfs-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.c | 194 | ||||
-rw-r--r-- | client/gdaemonmount.c | 3 | ||||
-rw-r--r-- | client/gvfsdaemondbus.c | 125 | ||||
-rw-r--r-- | client/gvfsdaemondbus.h | 6 | ||||
-rw-r--r-- | client/gvfsiconloadable.c | 13 |
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 |