Fix a _very_ subtle segfault in my two GTK container classes: the
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Mon, 31 Mar 2003 11:22:06 +0000 (11:22 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Mon, 31 Mar 2003 11:22:06 +0000 (11:22 +0000)
`forall' function has to be prepared for the list of widgets to
change along the way if (for example) the callback function destroys
its input widget.

git-svn-id: svn://svn.tartarus.org/sgt/putty@3029 cda61777-01e9-0310-a592-d414129be87e

unix/gtkcols.c
unix/gtkpanel.c

index d4c9367..c0a0ed8 100644 (file)
@@ -250,7 +250,7 @@ static void columns_forall(GtkContainer *container, gboolean include_internals,
 {
     Columns *cols;
     ColumnsChild *child;
-    GList *children;
+    GList *children, *next;
 
     g_return_if_fail(container != NULL);
     g_return_if_fail(IS_COLUMNS(container));
@@ -260,9 +260,19 @@ static void columns_forall(GtkContainer *container, gboolean include_internals,
 
     for (children = cols->children;
          children && (child = children->data);
-         children = children->next)
+         children = next) {
+        /*
+         * We can't wait until after the callback to assign
+         * `children = children->next', because the callback might
+         * be gtk_widget_destroy, which would remove the link
+         * `children' from the list! So instead we must get our
+         * hands on the value of the `next' pointer _before_ the
+         * callback.
+         */
+        next = children->next;
        if (child->widget)
            callback(child->widget, callback_data);
+    }
 }
 
 static GtkType columns_child_type(GtkContainer *container)
index c29fade..07ea867 100644 (file)
@@ -225,7 +225,7 @@ static void panels_forall(GtkContainer *container, gboolean include_internals,
 {
     Panels *panels;
     GtkWidget *child;
-    GList *children;
+    GList *children, *next;
 
     g_return_if_fail(container != NULL);
     g_return_if_fail(IS_PANELS(container));
@@ -235,9 +235,19 @@ static void panels_forall(GtkContainer *container, gboolean include_internals,
 
     for (children = panels->children;
          children && (child = children->data);
-         children = children->next)
+         children = next) {
+        /*
+         * We can't wait until after the callback to assign
+         * `children = children->next', because the callback might
+         * be gtk_widget_destroy, which would remove the link
+         * `children' from the list! So instead we must get our
+         * hands on the value of the `next' pointer _before_ the
+         * callback.
+         */
+        next = children->next;
        if (child)
            callback(child, callback_data);
+    }
 }
 
 static GtkType panels_child_type(GtkContainer *container)