return request;
}
+/** Allocate a request that's not in the free list
+ *
+ * This can be useful if modules need a persistent request for their own purposes
+ * which needs to be outside of the normal free list, so that it can be freed
+ * when the module requires, not when the thread destructor runs.
+ */
+REQUEST *request_alloc_local(TALLOC_CTX *ctx)
+{
+ REQUEST *request;
+
+ MEM(request = talloc_zero(ctx, REQUEST));
+
+ request_init(request);
+
+ return request;
+}
+
static REQUEST *request_init_fake(REQUEST *request, REQUEST *fake)
{
fake->number = request->child_number++;
REQUEST *request_alloc(TALLOC_CTX *ctx);
+REQUEST *request_alloc_local(TALLOC_CTX *ctx);
+
REQUEST *request_alloc_fake(REQUEST *parent, fr_dict_t const *namespace);
REQUEST *request_alloc_detachable(REQUEST *request, fr_dict_t const *namespace);
u = talloc_zero(c, fr_io_request_t);
- request = request_alloc(u);
+ /*
+ * Allocate outside of the free list.
+ * There appears to be an issue where
+ * the thread destructor runs too
+ * early, and frees the freelist's
+ * head before the module destructor
+ * runs.
+ */
+ request = request_alloc_local(u);
request->async = talloc_zero(request, fr_async_t);
talloc_const_free(request->name);
request->name = talloc_strdup(request, c->module_name);