]> jfr.im git - solanum.git/commitdiff
librb/event: delete indirectly via a dead flag
authorEd Kellett <redacted>
Sat, 3 Aug 2019 05:41:58 +0000 (06:41 +0100)
committerEd Kellett <redacted>
Sat, 7 Sep 2019 13:50:42 +0000 (14:50 +0100)
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
librb/src/event.c

index 4cabd31697b2bec00b5cbcea477e1810a7f51b6c..abb4d63b17f0f402e073bdbdeae70abc654d4e85 100644 (file)
@@ -33,5 +33,6 @@ struct ev_entry
        time_t next;
        void *data;
        void *comm_ptr;
+       int dead;
 };
 void rb_event_io_register_all(void);
index f678e3cce94faf37162a1329f69db52038e5af33..14755cc0ac284b3347b7d42851e6382272e17abf 100644 (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->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));