summaryrefslogtreecommitdiff
path: root/gio
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2007-12-12 19:34:19 +0000
committerAlexander Larsson <alexl@src.gnome.org>2007-12-12 19:34:19 +0000
commitafc16811d80d1ad63bb2e023f02e7b9d17767290 (patch)
treed6eaf0855452242f0e650ef6370c68b175e92861 /gio
parent1c57670f19012ac6ed8f4b0a0380ec0c304dd542 (diff)
downloadglib-afc16811d80d1ad63bb2e023f02e7b9d17767290.tar.gz
Fix race condition when freeing proxy in g_io_job_send_to_mainloop().
2007-12-12 Alexander Larsson <alexl@redhat.com> * gioscheduler.c: Fix race condition when freeing proxy in g_io_job_send_to_mainloop(). svn path=/trunk/; revision=6105
Diffstat (limited to 'gio')
-rw-r--r--gio/ChangeLog6
-rw-r--r--gio/gioscheduler.c32
2 files changed, 17 insertions, 21 deletions
diff --git a/gio/ChangeLog b/gio/ChangeLog
index ddbace754..ec3e80017 100644
--- a/gio/ChangeLog
+++ b/gio/ChangeLog
@@ -1,5 +1,11 @@
2007-12-12 Alexander Larsson <alexl@redhat.com>
+ * gioscheduler.c:
+ Fix race condition when freeing proxy in
+ g_io_job_send_to_mainloop().
+
+2007-12-12 Alexander Larsson <alexl@redhat.com>
+
* gfileattribute.c:
* gfileinfo.[ch]:
* glocalfile.c:
diff --git a/gio/gioscheduler.c b/gio/gioscheduler.c
index 61b7fbecb..f5607ae7a 100644
--- a/gio/gioscheduler.c
+++ b/gio/gioscheduler.c
@@ -291,6 +291,9 @@ mainloop_proxy_func (gpointer data)
proxy->func (proxy->data);
+ if (proxy->notify)
+ proxy->notify (proxy->data);
+
if (proxy->ack_lock)
{
g_mutex_lock (proxy->ack_lock);
@@ -313,19 +316,6 @@ mainloop_proxy_free (MainLoopProxy *proxy)
g_free (proxy);
}
-static void
-mainloop_proxy_notify (gpointer data)
-{
- MainLoopProxy *proxy = data;
-
- if (proxy->notify)
- proxy->notify (proxy->data);
-
- /* If nonblocking we free here, otherwise we free in io thread */
- if (proxy->ack_lock == NULL)
- mainloop_proxy_free (proxy);
-}
-
/**
* g_io_job_send_to_mainloop:
* @job: a #GIOJob.
@@ -355,7 +345,9 @@ g_io_job_send_to_mainloop (GIOJob *job,
/* We just immediately re-enter in the case of idles (non-threads)
* Anything else would just deadlock. If you can't handle this, enable threads.
*/
- func (user_data);
+ func (user_data);
+ if (notify)
+ notify (user_data);
return;
}
@@ -368,16 +360,14 @@ g_io_job_send_to_mainloop (GIOJob *job,
{
proxy->ack_lock = g_mutex_new ();
proxy->ack_condition = g_cond_new ();
+ g_mutex_lock (proxy->ack_lock);
}
source = g_idle_source_new ();
g_source_set_priority (source, G_PRIORITY_DEFAULT);
+ g_source_set_callback (source, mainloop_proxy_func, proxy,
+ block ? NULL : (GDestroyNotify)mainloop_proxy_free);
- g_source_set_callback (source, mainloop_proxy_func, proxy, mainloop_proxy_notify);
-
- if (block)
- g_mutex_lock (proxy->ack_lock);
-
id = g_source_attach (source, NULL);
g_source_unref (source);
@@ -385,8 +375,8 @@ g_io_job_send_to_mainloop (GIOJob *job,
{
g_cond_wait (proxy->ack_condition, proxy->ack_lock);
g_mutex_unlock (proxy->ack_lock);
-
- /* destroy notify didn't free proxy */
+
+ /* In the blocking case we free the proxy here */
mainloop_proxy_free (proxy);
}
}