librb/event: delete indirectly via a dead flag

This avoids an issue where deleting an event inside the handler of a
different event puts the event iteration in an invalid state.
This commit is contained in:
Ed Kellett 2019-08-03 06:41:58 +01:00
parent 9ac0390734
commit 3576d1b482
No known key found for this signature in database
GPG key ID: CB9986DEF342FABC
2 changed files with 11 additions and 3 deletions

View file

@ -33,5 +33,6 @@ struct ev_entry
time_t next; time_t next;
void *data; void *data;
void *comm_ptr; void *comm_ptr;
int dead;
}; };
void rb_event_io_register_all(void); void rb_event_io_register_all(void);

View file

@ -87,6 +87,7 @@ rb_event_add_common(const char *name, EVH * func, void *arg, time_t when, time_t
ev->when = rb_current_time() + when; ev->when = rb_current_time() + when;
ev->next = when; ev->next = when;
ev->frequency = frequency; ev->frequency = frequency;
ev->dead = 0;
if((ev->when < event_time_min) || (event_time_min == -1)) if((ev->when < event_time_min) || (event_time_min == -1))
event_time_min = ev->when; event_time_min = ev->when;
@ -142,10 +143,9 @@ rb_event_delete(struct ev_entry *ev)
if(ev == NULL) if(ev == NULL)
return; return;
rb_dlinkDelete(&ev->node, &event_list); ev->dead = 1;
rb_io_unsched_event(ev); rb_io_unsched_event(ev);
rb_free(ev->name);
rb_free(ev);
} }
/* /*
@ -228,6 +228,13 @@ rb_event_run(void)
RB_DLINK_FOREACH_SAFE(ptr, next, event_list.head) RB_DLINK_FOREACH_SAFE(ptr, next, event_list.head)
{ {
ev = ptr->data; ev = ptr->data;
if (ev->dead)
{
rb_dlinkDelete(&ev->node, &event_list);
rb_free(ev->name);
rb_free(ev);
continue;
}
if(ev->when <= rb_current_time()) if(ev->when <= rb_current_time())
{ {
rb_strlcpy(last_event_ran, ev->name, sizeof(last_event_ran)); rb_strlcpy(last_event_ran, ev->name, sizeof(last_event_ran));