[glib] gmain: Unref GSourceCallbackFuncs _before_ finalising GSource
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] gmain: Unref GSourceCallbackFuncs _before_ finalising GSource
- Date: Tue, 28 Nov 2017 15:02:26 +0000 (UTC)
commit 90dd9ff363729b2f797356515967c3b2a5f93b47
Author: Philip Withnall <philip withnall collabora co uk>
Date: Thu Sep 25 10:18:39 2014 +0100
gmain: Unref GSourceCallbackFuncs _before_ finalising GSource
Rather than unreffing them _after_ finalising the GSource and freeing
its struct. This fixes the case where the GSourceCallbackFuncs data
contains a pointer to the GSource, and the unref() function operates on
that pointer, e.g. by calling g_source_destroy(). This happens when
using g_source_set_dummy_callback() on a GSource, as the generated
GClosure needs to destroy the GSource when it is invalidated, which
could happen (at latest) when the GSourceCallbackFuncs.unref() function
is called during finalisation of the GSource.
By moving the GSourceCallbackFuncs.unref() invocation higher up in
g_source_unref_internal(), it becomes re-entrancy-safe for GSource
methods.
https://bugzilla.gnome.org/show_bug.cgi?id=692034
glib/gmain.c | 28 ++++++++++++++++------------
1 files changed, 16 insertions(+), 12 deletions(-)
---
diff --git a/glib/gmain.c b/glib/gmain.c
index 6a8a275..0f67c17 100644
--- a/glib/gmain.c
+++ b/glib/gmain.c
@@ -2122,6 +2122,21 @@ g_source_unref_internal (GSource *source,
source->ref_count--;
}
+ if (old_cb_funcs)
+ {
+ /* Temporarily increase the ref count again so that GSource methods
+ * can be called from callback_funcs.unref(). */
+ source->ref_count++;
+ if (context)
+ UNLOCK_CONTEXT (context);
+
+ old_cb_funcs->unref (old_cb_data);
+
+ if (context)
+ LOCK_CONTEXT (context);
+ source->ref_count--;
+ }
+
g_free (source->name);
source->name = NULL;
@@ -2146,20 +2161,9 @@ g_source_unref_internal (GSource *source,
g_free (source);
}
-
+
if (!have_lock && context)
UNLOCK_CONTEXT (context);
-
- if (old_cb_funcs)
- {
- if (have_lock)
- UNLOCK_CONTEXT (context);
-
- old_cb_funcs->unref (old_cb_data);
-
- if (have_lock)
- LOCK_CONTEXT (context);
- }
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]