[gnome-builder] egg-slider: re-entrant safety on ::forall
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] egg-slider: re-entrant safety on ::forall
- Date: Sun, 17 Jan 2016 17:23:21 +0000 (UTC)
commit 5bc8b69510cb1aac6e8673ebf71f7308cb86a607
Author: Christian Hergert <christian hergert me>
Date: Sun Jan 17 09:23:04 2016 -0800
egg-slider: re-entrant safety on ::forall
We need to be safe against gtk_widget_destroy() used as a callback, which
could mutate our priv->children array.
contrib/egg/egg-slider.c | 29 ++++++++++++++++++++++++-----
1 files changed, 24 insertions(+), 5 deletions(-)
---
diff --git a/contrib/egg/egg-slider.c b/contrib/egg/egg-slider.c
index ba68b29..09c23e3 100644
--- a/contrib/egg/egg-slider.c
+++ b/contrib/egg/egg-slider.c
@@ -365,17 +365,36 @@ egg_slider_forall (GtkContainer *container,
{
EggSlider *self = (EggSlider *)container;
EggSliderPrivate *priv = egg_slider_get_instance_private (self);
- gsize i;
+ GtkWidget **children;
+ guint len;
+ guint i;
g_assert (EGG_IS_SLIDER (self));
- for (i = 0; i < priv->children->len; i++)
+ /*
+ * We need to be widget re-entrant safe, meaning that the callback could
+ * remove a child during callback(), using gtk_widget_destroy or similar. So
+ * we create a local array containing a ref'd copy of all of the widgets in
+ * case the callback removes widgets.
+ */
+
+ len = priv->children->len;
+ children = g_new0 (GtkWidget *, len);
+
+ for (i = 0; i < len; i++)
{
- EggSliderChild *child;
+ EggSliderChild *child = g_ptr_array_index (priv->children, i);
- child = g_ptr_array_index (priv->children, i);
- callback (child->widget, callback_data);
+ children [i] = g_object_ref (child->widget);
+ }
+
+ for (i = 0; i < len; i++)
+ {
+ callback (children [i], callback_data);
+ g_object_unref (children [i]);
}
+
+ g_free (children);
}
static EggSliderChild *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]