[gnome-builder] egg-signal-group: Weak ref object in connect_object()
- From: Garrett Regier <gregier src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] egg-signal-group: Weak ref object in connect_object()
- Date: Thu, 14 May 2015 00:59:21 +0000 (UTC)
commit 56ea3d69f961debe3ab7f7f1dbc2223c2fe2e929
Author: Garrett Regier <garrettregier gmail com>
Date: Wed May 13 16:38:43 2015 -0700
egg-signal-group: Weak ref object in connect_object()
The handler must be removed and freed
when the object dies.
contrib/egg/egg-signal-group.c | 61 ++++++++++++++++++++++++++++++++++-----
1 files changed, 53 insertions(+), 8 deletions(-)
---
diff --git a/contrib/egg/egg-signal-group.c b/contrib/egg/egg-signal-group.c
index 70caf21..e4ddf7a 100644
--- a/contrib/egg/egg-signal-group.c
+++ b/contrib/egg/egg-signal-group.c
@@ -70,10 +70,12 @@ struct _EggSignalGroupClass
typedef struct
{
- gulong handler_id;
- GClosure *closure;
- const gchar *detailed_signal;
- guint connect_after : 1;
+ EggSignalGroup *group;
+ gulong handler_id;
+ GClosure *closure;
+ GObject *object;
+ const gchar *detailed_signal;
+ guint connect_after : 1;
} SignalHandler;
G_DEFINE_TYPE (EggSignalGroup, egg_signal_group, G_TYPE_OBJECT)
@@ -120,6 +122,33 @@ egg_signal_group__target_weak_notify (gpointer data,
}
static void
+egg_signal_group__connect_object_weak_notify (gpointer data,
+ GObject *where_object_was)
+{
+ EggSignalGroup *self = data;
+ gsize i;
+
+ g_assert (EGG_IS_SIGNAL_GROUP (self));
+ g_assert (where_object_was != NULL);
+
+ for (i = 0; i < self->handlers->len; ++i)
+ {
+ SignalHandler *handler;
+
+ handler = g_ptr_array_index (self->handlers, i);
+
+ if (handler->object == where_object_was)
+ {
+ handler->object = NULL;
+ g_ptr_array_remove_index_fast (self->handlers, i);
+ return;
+ }
+ }
+
+ g_critical ("Failed to find handler for %p", where_object_was);
+}
+
+static void
egg_signal_group_bind_handler (EggSignalGroup *self,
SignalHandler *handler)
{
@@ -366,6 +395,14 @@ signal_handler_free (gpointer data)
{
SignalHandler *handler = data;
+ if (handler->object != NULL)
+ {
+ g_object_weak_unref (handler->object,
+ egg_signal_group__connect_object_weak_notify,
+ handler->group);
+ handler->object = NULL;
+ }
+
g_clear_pointer (&handler->closure, g_closure_unref);
handler->handler_id = 0;
handler->detailed_signal = NULL;
@@ -568,17 +605,25 @@ egg_signal_group_connect_full (EggSignalGroup *self,
else
closure = g_cclosure_new (callback, data, notify);
- /* This is what g_cclosure_new_object() does */
- if (is_object)
- g_object_watch_closure (data, closure);
-
handler = g_slice_new0 (SignalHandler);
+ handler->group = self;
handler->detailed_signal = g_intern_string (detailed_signal);
handler->closure = g_closure_ref (closure);
handler->connect_after = ((flags & G_CONNECT_AFTER) != 0);
g_closure_sink (closure);
+ if (is_object)
+ {
+ /* This is what g_cclosure_new_object() does */
+ g_object_watch_closure (data, closure);
+
+ handler->object = data;
+ g_object_weak_ref (data,
+ egg_signal_group__connect_object_weak_notify,
+ self);
+ }
+
g_ptr_array_add (self->handlers, handler);
if (self->target != NULL)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]