[gvfs] Use new race-free cancellable signal connect APIs (#572844)
- From: Alexander Larsson <alexl src gnome org>
- To: svn-commits-list gnome org
- Subject: [gvfs] Use new race-free cancellable signal connect APIs (#572844)
- Date: Fri, 15 May 2009 14:16:42 -0400 (EDT)
commit 5bebce4592fee584bbc6db29a3e62b4005a1a71f
Author: Alexander Larsson <alexl redhat com>
Date: Fri May 15 10:47:49 2009 +0200
Use new race-free cancellable signal connect APIs (#572844)
---
client/gdaemonfileenumerator.c | 23 ++++++++++++++++++-----
common/gdbusutils.c | 9 ++++-----
daemon/gvfsbackendftp.c | 16 +++++++++-------
3 files changed, 31 insertions(+), 17 deletions(-)
diff --git a/client/gdaemonfileenumerator.c b/client/gdaemonfileenumerator.c
index 1aec092..b650eaf 100644
--- a/client/gdaemonfileenumerator.c
+++ b/client/gdaemonfileenumerator.c
@@ -162,6 +162,20 @@ trigger_async_done (GDaemonFileEnumerator *daemon, gboolean ok)
{
GList *rest, *l;
+ if (daemon->cancelled_tag != 0)
+ g_cancellable_disconnect (daemon->async_cancel,
+ daemon->cancelled_tag);
+
+ /* cancelled signal handler won't execute after this */
+
+ /* TODO: There is actually a small race here, where
+ trigger_async_done could happen twice if the operation
+ succeeds for some other reason and cancellation happens
+ on some other thread right before the above call.
+ However, this can only happen if cancellation happens
+ outside the main thread which is kinda unusual for async
+ ops. However, it would be nice to handle this too. */
+
if (ok)
{
l = daemon->infos;
@@ -181,9 +195,6 @@ trigger_async_done (GDaemonFileEnumerator *daemon, gboolean ok)
g_simple_async_result_complete_in_idle (daemon->async_res);
- if (daemon->cancelled_tag != 0)
- g_signal_handler_disconnect (daemon->async_cancel,
- daemon->cancelled_tag);
daemon->async_cancel = 0;
daemon->cancelled_tag = 0;
@@ -400,10 +411,12 @@ g_daemon_file_enumerator_next_files_async (GFileEnumerator *enumerator,
trigger_async_done (daemon, TRUE);
else
{
- if (cancellable)
- daemon->cancelled_tag = g_signal_connect (cancellable, "cancelled", (GCallback)async_cancelled, daemon);
daemon->timeout_tag = g_timeout_add (G_VFS_DBUS_TIMEOUT_MSECS,
async_timeout, daemon);
+ if (cancellable)
+ daemon->cancelled_tag =
+ g_cancellable_connect (cancellable, (GCallback)async_cancelled,
+ daemon, NULL);
}
G_UNLOCK (infos);
diff --git a/common/gdbusutils.c b/common/gdbusutils.c
index c3f3f33..f9d1889 100644
--- a/common/gdbusutils.c
+++ b/common/gdbusutils.c
@@ -679,8 +679,8 @@ fd_source_finalize (GSource *source)
FDSource *fd_source = (FDSource *)source;
if (fd_source->cancelled_tag)
- g_signal_handler_disconnect (fd_source->cancellable,
- fd_source->cancelled_tag);
+ g_cancellable_disconnect (fd_source->cancellable,
+ fd_source->cancelled_tag);
if (fd_source->cancellable)
g_object_unref (fd_source->cancellable);
@@ -723,10 +723,9 @@ __g_fd_source_new (int fd,
if (cancellable)
fd_source->cancelled_tag =
- g_signal_connect_data (cancellable, "cancelled",
+ g_cancellable_connect (cancellable,
(GCallback)fd_source_cancelled_cb,
- NULL, NULL,
- 0);
+ NULL, NULL);
return source;
}
diff --git a/daemon/gvfsbackendftp.c b/daemon/gvfsbackendftp.c
index e434122..0af9287 100644
--- a/daemon/gvfsbackendftp.c
+++ b/daemon/gvfsbackendftp.c
@@ -1316,19 +1316,21 @@ g_vfs_backend_ftp_pop_connection (GVfsBackendFtp *ftp,
{
FtpConnection *conn = NULL;
GTimeVal now;
- guint id;
+ gulong id;
+
+ if (g_cancellable_is_cancelled (job->cancellable))
+ return NULL;
g_mutex_lock (ftp->mutex);
- id = g_signal_connect (job->cancellable,
- "cancelled",
- G_CALLBACK (do_broadcast),
- ftp->cond);
+ id = g_cancellable_connect (job->cancellable,
+ G_CALLBACK (do_broadcast),
+ ftp->cond, NULL);
while (conn == NULL && ftp->queue != NULL)
{
if (g_cancellable_is_cancelled (job->cancellable))
break;
- conn = g_queue_pop_head (ftp->queue);
+ conn = g_queue_pop_head (ftp->queue);
if (conn != NULL)
{
/* Figure out if this connection had a timeout sent. If so, skip it. */
@@ -1393,7 +1395,7 @@ g_vfs_backend_ftp_pop_connection (GVfsBackendFtp *ftp,
break;
}
}
- g_signal_handler_disconnect (job->cancellable, id);
+ g_cancellable_disconnect (job->cancellable, id);
return conn;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]