[glib] binding: Make unbind() release the reference on GBinding
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] binding: Make unbind() release the reference on GBinding
- Date: Wed, 12 Jun 2013 10:28:09 +0000 (UTC)
commit 25a3c8720cb13944eb051775b89838540d4c5760
Author: Emmanuele Bassi <ebassi gnome org>
Date: Thu May 16 22:28:54 2013 +0100
binding: Make unbind() release the reference on GBinding
The automatic memory management of GBinding is not optimal for high
order languages with garbage collectors semantics. If we leave the
binding instance inert but still referenced it will be leaked, so one
solution that does not throw away the baby of C convenience with the
bathwater of language bindability is to have unbind() perform an
implicit unref().
Hopefully, C developers will read the documentation and especially the
note that says that after calling unbind() the reference count on the
GBinding instance is decreased.
https://bugzilla.gnome.org/show_bug.cgi?id=698018
gobject/gbinding.c | 81 +++++++++++++++++++++++++++-------------------
gobject/tests/binding.c | 4 +--
2 files changed, 48 insertions(+), 37 deletions(-)
---
diff --git a/gobject/gbinding.c b/gobject/gbinding.c
index 714bb1c..fd152b9 100644
--- a/gobject/gbinding.c
+++ b/gobject/gbinding.c
@@ -435,12 +435,53 @@ on_target_notify (GObject *gobject,
g_value_unset (&target_value);
}
+static inline void
+g_binding_unbind_internal (GBinding *binding,
+ gboolean unref_binding)
+{
+ /* dispose of the transformation data */
+ if (binding->notify != NULL)
+ {
+ binding->notify (binding->transform_data);
+
+ binding->transform_data = NULL;
+ binding->notify = NULL;
+ }
+
+ if (binding->source != NULL)
+ {
+ if (binding->source_notify != 0)
+ g_signal_handler_disconnect (binding->source, binding->source_notify);
+
+ g_object_weak_unref (binding->source, weak_unbind, binding);
+ remove_binding_qdata (binding->source, binding);
+
+ binding->source_notify = 0;
+ binding->source = NULL;
+ }
+
+ if (binding->target != NULL)
+ {
+ if (binding->target_notify != 0)
+ g_signal_handler_disconnect (binding->target, binding->target_notify);
+
+ g_object_weak_unref (binding->target, weak_unbind, binding);
+ remove_binding_qdata (binding->target, binding);
+
+ binding->target_notify = 0;
+ binding->target = NULL;
+ }
+
+ if (unref_binding)
+ g_object_unref (binding);
+}
+
static void
g_binding_finalize (GObject *gobject)
{
GBinding *binding = G_BINDING (gobject);
- g_binding_unbind (binding);
+ g_binding_unbind_internal (binding, FALSE);
G_OBJECT_CLASS (g_binding_parent_class)->finalize (gobject);
}
@@ -759,7 +800,10 @@ g_binding_get_target_property (GBinding *binding)
* Explicitly releases the binding between the source and the target
* property expressed by @binding.
*
- * This function does not change the reference count of @binding.
+ * <note>This function will release the reference that is being held on
+ * the @binding instance; if you want to hold on to the #GBinding instance
+ * after calling g_binding_unbind(), you will need to hold a reference
+ * to it.</note>
*
* Since: 2.38
*/
@@ -768,38 +812,7 @@ g_binding_unbind (GBinding *binding)
{
g_return_if_fail (G_IS_BINDING (binding));
- /* dispose of the transformation data */
- if (binding->notify != NULL)
- {
- binding->notify (binding->transform_data);
-
- binding->transform_data = NULL;
- binding->notify = NULL;
- }
-
- if (binding->source != NULL)
- {
- if (binding->source_notify != 0)
- g_signal_handler_disconnect (binding->source, binding->source_notify);
-
- g_object_weak_unref (binding->source, weak_unbind, binding);
- remove_binding_qdata (binding->source, binding);
-
- binding->source_notify = 0;
- binding->source = NULL;
- }
-
- if (binding->target != NULL)
- {
- if (binding->target_notify != 0)
- g_signal_handler_disconnect (binding->target, binding->target_notify);
-
- g_object_weak_unref (binding->target, weak_unbind, binding);
- remove_binding_qdata (binding->target, binding);
-
- binding->target_notify = 0;
- binding->target = NULL;
- }
+ g_binding_unbind_internal (binding, TRUE);
}
/**
diff --git a/gobject/tests/binding.c b/gobject/tests/binding.c
index 7f7121e..9eba7b5 100644
--- a/gobject/tests/binding.c
+++ b/gobject/tests/binding.c
@@ -590,15 +590,13 @@ binding_unbind (void)
g_assert_cmpint (source->foo, !=, target->bar);
g_binding_unbind (binding);
- g_assert (binding != NULL);
+ g_assert (binding == NULL);
g_object_set (source, "foo", 0, NULL);
g_assert_cmpint (source->foo, !=, target->bar);
g_object_unref (source);
g_object_unref (target);
- g_object_unref (binding);
- g_assert (binding == NULL);
}
int
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]