From 42d3ed001353560892b9b25b2fa93b974a3df480 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Fri, 14 Feb 2014 16:03:49 -0500 Subject: [PATCH] glib: document restrictions on various foreach() functions Some foreach() functions allow you to modify the object they are iterating, and others don't, but the docs were not generally clear about this. https://bugzilla.gnome.org/show_bug.cgi?id=724383 --- glib/garray.c | 3 ++- glib/gdataset.c | 12 ++++++++++-- glib/glist.c | 6 ++++++ glib/gnode.c | 6 ++++-- glib/gqueue.c | 6 ++++++ glib/gsequence.c | 5 +++-- glib/gslist.c | 6 ++++++ 7 files changed, 37 insertions(+), 7 deletions(-) diff --git a/glib/garray.c b/glib/garray.c index a4762842f..5670408fd 100644 --- a/glib/garray.c +++ b/glib/garray.c @@ -1503,7 +1503,8 @@ g_ptr_array_sort_with_data (GPtrArray *array, * @func: the function to call for each array element * @user_data: user data to pass to the function * - * Calls a function for each element of a #GPtrArray. + * Calls a function for each element of a #GPtrArray. @func must not + * add elements to or remove elements from the array. * * Since: 2.4 */ diff --git a/glib/gdataset.c b/glib/gdataset.c index ae36e9e2f..cc4397ca5 100644 --- a/glib/gdataset.c +++ b/glib/gdataset.c @@ -1065,8 +1065,12 @@ g_datalist_get_data (GData **datalist, * * Calls the given function for each data element which is associated * with the given location. Note that this function is NOT thread-safe. - * So unless @datalist can be protected from any modifications during - * invocation of this function, it should not be called. + * So unless @dataset_location can be protected from any modifications + * during invocation of this function, it should not be called. + * + * @func can make changes to the dataset, but the iteration will not + * reflect changes made during the g_dataset_foreach() call, other + * than skipping over elements that are removed. **/ void g_dataset_foreach (gconstpointer dataset_location, @@ -1104,6 +1108,10 @@ g_dataset_foreach (gconstpointer dataset_location, * function is NOT thread-safe. So unless @datalist can be protected * from any modifications during invocation of this function, it should * not be called. + * + * @func can make changes to @datalist, but the iteration will not + * reflect changes made during the g_datalist_foreach() call, other + * than skipping over elements that are removed. **/ void g_datalist_foreach (GData **datalist, diff --git a/glib/glist.c b/glib/glist.c index 2b5692ee9..6f2079a4c 100644 --- a/glib/glist.c +++ b/glib/glist.c @@ -211,6 +211,9 @@ g_list_free_1 (GList *list) * Convenience method, which frees all the memory used by a #GList, * and calls @free_func on every element's data. * + * @free_func must not modify the list (eg, by removing the freed + * element from it). + * * Since: 2.28 */ void @@ -985,6 +988,9 @@ g_list_length (GList *list) * @user_data: user data to pass to the function * * Calls a function for each element of a #GList. + * + * It is safe for @func to remove the element from @list, but it must + * not modify any part of the list after that element. */ /** * GFunc: diff --git a/glib/gnode.c b/glib/gnode.c index 51c9fdc80..9d5ff5792 100644 --- a/glib/gnode.c +++ b/glib/gnode.c @@ -816,6 +816,7 @@ g_node_depth_traverse_level (GNode *node, * Traverses a tree starting at the given root #GNode. * It calls the given function for each node visited. * The traversal can be halted at any point by returning %TRUE from @func. + * @func must not do anything that would modify the structure of the tree. */ /** @@ -1235,8 +1236,9 @@ g_node_last_sibling (GNode *node) * @func: the function to call for each visited node * @data: user data to pass to the function * - * Calls a function for each of the children of a #GNode. - * Note that it doesn't descend beneath the child nodes. + * Calls a function for each of the children of a #GNode. Note that it + * doesn't descend beneath the child nodes. @func must not do anything + * that would modify the structure of the tree. */ /** * GNodeForeachFunc: diff --git a/glib/gqueue.c b/glib/gqueue.c index 01bd13439..26fe507a3 100644 --- a/glib/gqueue.c +++ b/glib/gqueue.c @@ -95,6 +95,9 @@ g_queue_free (GQueue *queue) * Convenience method, which frees all the memory used by a #GQueue, * and calls the specified destroy function on every element's data. * + * @free_func should not modify the queue (eg, by removing the freed + * element from it). + * * Since: 2.32 */ void @@ -231,6 +234,9 @@ g_queue_copy (GQueue *queue) * Calls @func for each element in the queue passing @user_data to the * function. * + * It is safe for @func to remove the element from @queue, but it must + * not modify any part of the queue after that element. + * * Since: 2.4 */ void diff --git a/glib/gsequence.c b/glib/gsequence.c index a67f2576f..2dac88a94 100644 --- a/glib/gsequence.c +++ b/glib/gsequence.c @@ -294,7 +294,8 @@ g_sequence_free (GSequence *seq) * @user_data: user data passed to @func * * Calls @func for each item in the range (@begin, @end) passing - * @user_data to the function. + * @user_data to the function. @func must not modify the sequence + * itself. * * Since: 2.14 */ @@ -335,7 +336,7 @@ g_sequence_foreach_range (GSequenceIter *begin, * @user_data: user data passed to @func * * Calls @func for each item in the sequence passing @user_data - * to the function. + * to the function. @func must not modify the sequence itself. * * Since: 2.14 */ diff --git a/glib/gslist.c b/glib/gslist.c index 028237d3d..bc29b4101 100644 --- a/glib/gslist.c +++ b/glib/gslist.c @@ -165,6 +165,9 @@ g_slist_free_1 (GSList *list) * Convenience method, which frees all the memory used by a #GSList, and * calls the specified destroy function on every element's data. * + * @free_func must not modify the list (eg, by removing the freed + * element from it). + * * Since: 2.28 **/ void @@ -844,6 +847,9 @@ g_slist_length (GSList *list) * @user_data: user data to pass to the function * * Calls a function for each element of a #GSList. + * + * It is safe for @func to remove the element from @list, but it must + * not modify any part of the list after that element. */ void g_slist_foreach (GSList *list,