/** Creates a heap that can be used with non-talloced elements
*
+ * @param[in] _ctx Talloc ctx to allocate heap in.
* @param[in] _cmp Comparator used to compare elements.
* @param[in] _type Of elements.
* @param[in] _field to store heap indexes in.
*/
-#define fr_heap_create(_cmp, _type, _field) \
- _fr_heap_create(_cmp, NULL, (size_t)offsetof(_type, _field))
+#define fr_heap_create(_ctx, _cmp, _type, _field) \
+ _fr_heap_create(_ctx, _cmp, NULL, (size_t)offsetof(_type, _field))
/** Creates a heap that verifies elements are of a specific talloc type
*
+ * @param[in] _ctx Talloc ctx to allocate heap in.
* @param[in] _cmp Comparator used to compare elements.
* @param[in] _talloc_type of elements.
* @param[in] _field to store heap indexes in.
* - A new heap.
* - NULL on error.
*/
-#define fr_heap_talloc_create(_cmp, _talloc_type, _field) \
- _fr_heap_create(_cmp, #_talloc_type, (size_t)offsetof(_talloc_type, _field))
+#define fr_heap_talloc_create(_ctx, _cmp, _talloc_type, _field) \
+ _fr_heap_create(_ctx, _cmp, #_talloc_type, (size_t)offsetof(_talloc_type, _field))
-fr_heap_t *_fr_heap_create(fr_heap_cmp_t cmp, char const *talloc_type, size_t offset);
+fr_heap_t *_fr_heap_create(TALLOC_CTX *ctx, fr_heap_cmp_t cmp, char const *talloc_type, size_t offset);
int fr_heap_insert(fr_heap_t *hp, void *data);
int fr_heap_extract(fr_heap_t *hp, void *data);
rad_assert(s != NULL);
memcpy(&s->listen, data, sizeof(s->listen));
- MEM(s->waiting = fr_heap_create(waiting_cmp, fr_channel_data_t, channel.heap_id));
+ MEM(s->waiting = fr_heap_create(s, waiting_cmp, fr_channel_data_t, channel.heap_id));
FR_DLIST_INIT(s->entry);
talloc_set_destructor(s, _network_socket_free);
rad_assert(s != NULL);
memcpy(&s->listen, data, sizeof(s->listen));
- MEM(s->waiting = fr_heap_create(waiting_cmp, fr_channel_data_t, channel.heap_id));
+ MEM(s->waiting = fr_heap_create(s, waiting_cmp, fr_channel_data_t, channel.heap_id));
FR_DLIST_INIT(s->entry);
talloc_set_destructor(s, _network_socket_free);
goto fail2;
}
- nr->replies = fr_heap_create(reply_cmp, fr_channel_data_t, channel.heap_id);
+ nr->replies = fr_heap_create(nr, reply_cmp, fr_channel_data_t, channel.heap_id);
if (!nr->replies) {
fr_strerror_printf_push("Failed creating heap for replies");
goto fail2;
*/
#define WORKER_HEAP_INIT(_name, _func, _type, _member) do { \
FR_DLIST_INIT(worker->_name.list); \
- worker->_name.heap = fr_heap_create(_func, _type, _member); \
+ worker->_name.heap = fr_heap_create(worker, _func, _type, _member); \
if (!worker->_name.heap) { \
(void) fr_event_user_delete(worker->el, fr_worker_evfilt_user, worker); \
talloc_free(worker); \
worker_stop_request(worker, request, now);
talloc_free(request);
}
- talloc_free(worker->time_order);
-
rad_assert(fr_heap_num_elements(worker->runnable) == 0);
- talloc_free(worker->runnable);
#if 0
/*
WORKER_HEAP_INIT(to_decode, worker_message_cmp, fr_channel_data_t, channel.heap_id);
WORKER_HEAP_INIT(localized, worker_message_cmp, fr_channel_data_t, channel.heap_id);
- worker->runnable = fr_heap_talloc_create(worker_runnable_cmp, REQUEST, runnable_id);
+ worker->runnable = fr_heap_talloc_create(worker, worker_runnable_cmp, REQUEST, runnable_id);
if (!worker->runnable) {
fr_strerror_printf("Failed creating runnable heap");
goto fail;
}
- worker->time_order = fr_heap_talloc_create(worker_time_order_cmp, REQUEST, time_order_id);
+ worker->time_order = fr_heap_talloc_create(worker, worker_time_order_cmp, REQUEST, time_order_id);
if (!worker->time_order) {
fr_strerror_printf("Failed creating time_order heap");
goto fail;
while ((ev = fr_heap_peek(el->times)) != NULL) fr_event_timer_delete(el, &ev);
- talloc_free(el->times);
-
talloc_free_children(el);
if (el->kq >= 0) close(el->kq);
el->kq = -1; /* So destructor can be used before kqueue() provides us with fd */
talloc_set_destructor(el, _event_list_free);
- el->times = fr_heap_talloc_create(fr_event_timer_cmp, fr_event_timer_t, heap_id);
+ el->times = fr_heap_talloc_create(el, fr_event_timer_cmp, fr_event_timer_t, heap_id);
if (!el->times) {
fr_strerror_printf("Failed allocating event heap");
error:
static void fr_heap_bubble(fr_heap_t *hp, int32_t child);
-fr_heap_t *_fr_heap_create(fr_heap_cmp_t cmp, char const *type, size_t offset)
+fr_heap_t *_fr_heap_create(TALLOC_CTX *ctx, fr_heap_cmp_t cmp, char const *type, size_t offset)
{
fr_heap_t *fh;
if (!cmp) return NULL;
- fh = talloc_zero(NULL, fr_heap_t);
+ fh = talloc_zero(ctx, fr_heap_t);
if (!fh) return NULL;
fh->size = 2048;
skip = atoi(argv[1]);
}
- hp = fr_heap_create(heap_cmp, offsetof(heap_thing, heap_id));
+ hp = fr_heap_create(NULL, heap_cmp, offsetof(heap_thing, heap_id));
if (!hp) {
fprintf(stderr, "Failed creating heap!\n");
fr_exit(1);
{
module_thread_instance_t *ti = talloc_get_type_abort(to_free, module_thread_instance_t);
- if (ti->module->thread_detach) {
- (void) ti->module->thread_detach(ti->el, ti->data);
- }
+ DEBUG3("Worker cleaning up %s thread instance data (%p/%p)", ti->module->name, ti, ti->data);
+ if (ti->module->thread_detach) (void) ti->module->thread_detach(ti->el, ti->data);
talloc_free(ti);
}
{
rbtree_t *thread_inst_tree = talloc_get_type_abort(to_free , rbtree_t);
+ DEBUG3("Worker cleaning up thread instance tree");
+
talloc_free(thread_inst_tree);
}
MEM(type_name = talloc_typed_asprintf(NULL, "rlm_%s_thread_t", mi->module->name));
talloc_set_name(ti->data, "%s", type_name);
talloc_free(type_name);
-
}
+ DEBUG3("Worker alloced %s thread instance data (%p/%p)", ti->module->name, ti, ti->data);
if (mi->module->thread_instantiate) {
ret = mi->module->thread_instantiate(mi->dl_inst->conf, mi->dl_inst->data,
- thread_inst_ctx->el, ti->data);
+ thread_inst_ctx->el, ti->data);
if (ret < 0) {
- ERROR("Thread instantiation failed for module \"%s\"",
- mi->name);
+ ERROR("Thread instantiation failed for module \"%s\"", mi->name);
return -1;
}
}
-
rbtree_insert(thread_inst_ctx->tree, ti);
return 0;
* https://code.facebook.com/posts/1499322996995183/solving-the-mystery-of-link-imbalance-a-metastable-failure-state-at-scale/
*/
if (!pool->spread) {
- pool->heap = fr_heap_talloc_create(last_reserved_cmp, fr_pool_connection_t, heap_id);
+ pool->heap = fr_heap_talloc_create(pool, last_reserved_cmp, fr_pool_connection_t, heap_id);
/*
* For some types of connections we need to used a different
* algorithm, because load balancing benefits are secondary
* That way we maximise time between connection use.
*/
} else {
- pool->heap = fr_heap_talloc_create(last_released_cmp, fr_pool_connection_t, heap_id);
+ pool->heap = fr_heap_talloc_create(pool, last_released_cmp, fr_pool_connection_t, heap_id);
}
if (!pool->heap) {
ERROR("%s: Failed creating connection heap", __FUNCTION__);
connection_close_internal(pool, NULL, this);
}
- talloc_free(pool->heap);
-
fr_pool_trigger_exec(pool, NULL, "stop");
rad_assert(pool->head == NULL);
{
rlm_cache_rbtree_t *driver = talloc_get_type_abort(instance, rlm_cache_rbtree_t);
- if (driver->heap) talloc_free(driver->heap);
if (driver->cache) {
rbtree_walk(driver->cache, RBTREE_DELETE_ORDER, _cache_entry_free, NULL);
talloc_free(driver->cache);
/*
* The heap of entries to expire.
*/
- driver->heap = fr_heap_talloc_create(cache_heap_cmp, rlm_cache_rbtree_entry_t, heap_id);
+ driver->heap = fr_heap_talloc_create(driver, cache_heap_cmp, rlm_cache_rbtree_entry_t, heap_id);
if (!driver->heap) {
ERROR("Failed to create heap for the cache");
return -1;
t->inst = instance;
t->el = el;
- t->queued = fr_heap_talloc_create(queue_cmp, rlm_radius_udp_request_t, heap_id);
+ t->queued = fr_heap_talloc_create(t, queue_cmp, rlm_radius_udp_request_t, heap_id);
FR_DLIST_INIT(t->blocked);
FR_DLIST_INIT(t->full);
FR_DLIST_INIT(t->zombie);
FR_DLIST_INIT(t->opening);
- t->active = fr_heap_talloc_create(conn_cmp, rlm_radius_udp_connection_t, heap_id);
+ t->active = fr_heap_talloc_create(t, conn_cmp, rlm_radius_udp_connection_t, heap_id);
conn_alloc(t->inst, t);
* Free all of the heaps, lists, and sockets.
*/
talloc_free_children(t);
- talloc_free(t->queued);
- talloc_free(t->active);
entry = FR_DLIST_FIRST(t->opening);
if (entry != NULL) {
return RLM_MODULE_FAIL;
}
- MEM(backlog = fr_heap_talloc_create(_unlang_request_ptr_cmp, REQUEST, runnable_id));
+ MEM(backlog = fr_heap_talloc_create(el, _unlang_request_ptr_cmp, REQUEST, runnable_id));
old_el = request->el;
old_backlog = request->backlog;
caller = request->module;
talloc_free(el);
request->el = old_el;
- talloc_free(backlog);
request->backlog = old_backlog;
request->module = caller;