[libdazzle] signal-group: be more flexible in cleanup
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libdazzle] signal-group: be more flexible in cleanup
- Date: Fri, 12 Jan 2018 22:33:24 +0000 (UTC)
commit bfeb73ed739fe50d525a91ddfd2c0d09be657b2a
Author: Christian Hergert <chergert redhat com>
Date: Fri Jan 12 14:30:33 2018 -0800
signal-group: be more flexible in cleanup
- Ensure we hold a reference during cleanup, so that the object
cannot be finalized out from underneath us.
- Don't disconnect if we lost our target.
- Code style cleanup
src/bindings/dzl-signal-group.c | 48 +++++++++++++++++++++++++----------------
1 file changed, 29 insertions(+), 19 deletions(-)
---
diff --git a/src/bindings/dzl-signal-group.c b/src/bindings/dzl-signal-group.c
index 011b5a2..cfbf294 100644
--- a/src/bindings/dzl-signal-group.c
+++ b/src/bindings/dzl-signal-group.c
@@ -233,24 +233,32 @@ dzl_signal_group_bind (DzlSignalGroup *self,
static void
dzl_signal_group_unbind (DzlSignalGroup *self)
{
- GObject *target;
- gsize i;
+ g_autoptr(GObject) target = NULL;
g_return_if_fail (DZL_IS_SIGNAL_GROUP (self));
- if (self->target == NULL)
- return;
-
- target = self->target;
- self->target = NULL;
-
- g_object_weak_unref (target,
- dzl_signal_group__target_weak_notify,
- self);
+ if (NULL != (target = g_steal_pointer (&self->target)))
+ {
+ /*
+ * If we have a valid target, we want to hold a reference to it
+ * while we do the disconnections, just to ensure it is not
+ * finalized out from underneath us.
+ */
+ g_object_ref (target);
+
+ /*
+ * Let go of our weak reference now that we have a full reference
+ * for the life of this function.
+ */
+ g_object_weak_unref (target,
+ dzl_signal_group__target_weak_notify,
+ self);
+ }
- for (i = 0; i < self->handlers->len; i++)
+ for (guint i = 0; i < self->handlers->len; i++)
{
SignalHandler *handler;
+ gulong handler_id;
handler = g_ptr_array_index (self->handlers, i);
@@ -258,15 +266,17 @@ dzl_signal_group_unbind (DzlSignalGroup *self)
g_assert (handler->signal_id != 0);
g_assert (handler->closure != NULL);
- if (handler->handler_id != 0)
- {
- gulong handler_id;
+ handler_id = handler->handler_id;
+ handler->handler_id = 0;
- handler_id = handler->handler_id;
- handler->handler_id = 0;
+ /*
+ * If @target is NULL, we lost a race to cleanup the weak
+ * instance and the signal connections have already been
+ * finalized and therefore nothing to do.
+ */
- g_signal_handler_disconnect (target, handler_id);
- }
+ if (target != NULL && handler_id != 0)
+ g_signal_handler_disconnect (target, handler_id);
}
g_signal_emit (self, signals [UNBIND], 0);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]