From 3576d1b482728af41b4de3e7022262dec286d2f1 Mon Sep 17 00:00:00 2001 From: Ed Kellett Date: Sat, 3 Aug 2019 06:41:58 +0100 Subject: [PATCH] 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. --- librb/include/event-int.h | 1 + librb/src/event.c | 13 ++++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/librb/include/event-int.h b/librb/include/event-int.h index 4cabd316..abb4d63b 100644 --- a/librb/include/event-int.h +++ b/librb/include/event-int.h @@ -33,5 +33,6 @@ struct ev_entry time_t next; void *data; void *comm_ptr; + int dead; }; void rb_event_io_register_all(void); diff --git a/librb/src/event.c b/librb/src/event.c index f678e3cc..14755cc0 100644 --- a/librb/src/event.c +++ b/librb/src/event.c @@ -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->next = when; ev->frequency = frequency; + ev->dead = 0; if((ev->when < event_time_min) || (event_time_min == -1)) event_time_min = ev->when; @@ -142,10 +143,9 @@ rb_event_delete(struct ev_entry *ev) if(ev == NULL) return; - rb_dlinkDelete(&ev->node, &event_list); + ev->dead = 1; + 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) { 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()) { rb_strlcpy(last_event_ran, ev->name, sizeof(last_event_ran));