static int track_dedup_free(fr_io_track_t *track)
{
fr_assert(track->client->table != NULL);
+
+ /*
+ * If the tree is being freed, then we don't try to remove ourselves from it. Doing so would
+ * free this node, and therefore corrupt the tree.
+ *
+ * The talloc code will take care of cleaning up the children and events when this chunk is
+ * freed.
+ */
+ if (track->client->table->being_freed) return 0;
+
fr_assert(fr_rb_find(track->client->table, track) != NULL);
if (!fr_rb_delete(track->client->table, track)) {
* there are no duplicates, so this is fine.
*/
if (client->connection) {
- MEM(track = talloc_zero_pooled_object(client, fr_io_track_t, 1, sizeof(*track) + 64));
+ MEM(track = talloc_zero_pooled_object(client->table, fr_io_track_t, 1, sizeof(*track) + 64));
track->address = client->connection->address;
} else {
fr_io_address_t *my_address;
- MEM(track = talloc_zero_pooled_object(client, fr_io_track_t, 1, sizeof(*track) + sizeof(*track->address) + 64));
+ MEM(track = talloc_zero_pooled_object(client->table, fr_io_track_t, 1, sizeof(*track) + sizeof(*track->address) + 64));
MEM(track->address = my_address = talloc(track, fr_io_address_t));
*my_address = *address;
MEM(client = client_alloc(thread, PR_CLIENT_STATIC, inst, thread, radclient, NULL));
}
- MEM(track = talloc_zero_pooled_object(client, fr_io_track_t, 1, sizeof(*track) + sizeof(*track->address) + 64));
+ MEM(track = talloc_zero_pooled_object(client->table, fr_io_track_t, 1, sizeof(*track) + sizeof(*track->address) + 64));
MEM(track->address = address = talloc_zero(track, fr_io_address_t));
track->li = li;
return -1;
}
- if (fr_rb_node_inline_in_tree(&mi->name_node) && !fr_cond_assert(fr_rb_delete(ml->name_tree, mi))) return 1;
- if (fr_rb_node_inline_in_tree(&mi->data_node) && !fr_cond_assert(fr_rb_delete(ml->data_tree, mi))) return 1;
+ /*
+ * If the tree is being freed, then we don't try to remove ourselves from it. Doing so would
+ * free this node, and therefore corrupt the tree.
+ *
+ * The talloc code will take care of cleaning up the children and events when this chunk is
+ * freed.
+ */
+ if (!ml->name_tree->being_freed) {
+ if (fr_rb_node_inline_in_tree(&mi->name_node) && !fr_cond_assert(fr_rb_delete(ml->name_tree, mi))) return 1;
+ }
+
+ if (!ml->data_tree->being_freed) {
+ if (fr_rb_node_inline_in_tree(&mi->data_node) && !fr_cond_assert(fr_rb_delete(ml->data_tree, mi))) return 1;
+ }
if (ml->type->data_del) ml->type->data_del(mi);
/*
*/
if ((tree->root != NIL) && tree->data_free) free_walker(tree, tree->root);
-#ifndef NDEBUG
- tree->magic = 0;
-#endif
- tree->root = NIL;
- tree->num_elements = 0;
-
/*
* Ensure all dependents on the tree run their
* destructors. The tree at this point should
*/
talloc_free_children(tree);
+#ifndef NDEBUG
+ tree->magic = 0;
+#endif
+ tree->root = NIL;
+ tree->num_elements = 0;
+
return 0;
}