-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Open
Description
Libevent's timer min-heap only supports one-way expansion and does not support contraction. Therefore, after adding many timer events for a period of time and then deleting these events, the memory of the min-heap remains in an expanded state.
The below function will allocate sufficient memory:
int min_heap_reserve_(min_heap_t* s, unsigned n)
{
if (s->a < n)
{
struct event** p;
unsigned a = s->a ? s->a * 2 : 8;
if (a < n)
a = n;
if (!(p = (struct event**)mm_realloc(s->p, a * sizeof *p)))
return -1;
s->p = p;
s->a = a;
}
return 0;
}
but, the function min_heap_erase_ only sets the index of the removed event to -1,
int min_heap_erase_(min_heap_t* s, struct event* e)
{
if (-1 != e->ev_timeout_pos.min_heap_idx)
{
struct event *last = s->p[--s->n];
unsigned parent = (e->ev_timeout_pos.min_heap_idx - 1) / 2;
if (e->ev_timeout_pos.min_heap_idx > 0 && min_heap_elem_greater(s->p[parent], last))
min_heap_shift_up_unconditional_(s, e->ev_timeout_pos.min_heap_idx, last);
else
min_heap_shift_down_(s, e->ev_timeout_pos.min_heap_idx, last);
e->ev_timeout_pos.min_heap_idx = -1;
return 0;
}
return -1;
}
Is this design intentional for a specific purpose? Where is the expanded memory released? Otherwise, if more and more timers keep getting added and then removed, wouldn't the memory usage keep growing? Unless the entire base event loop is released, that memory won't be fully cleaned up.
Metadata
Metadata
Assignees
Labels
No labels