Change flush_events() to expire_events().

The former function made a totally bogus shallow copy of the event_tree, called
the handler of each event and then deleted the whole tree.  This should've
caused tinc to crash when an ALARM signal was sent more than once, but for some
reason it didn't. It also behaved incorrectly when a handler added a new event.

The new function just moves the expiration time of all events to the past.
This commit is contained in:
Guus Sliepen 2009-01-19 22:50:05 +01:00
parent a39a9506cd
commit 116065afe3
3 changed files with 25 additions and 20 deletions

View file

@ -47,7 +47,7 @@ void init_events(void)
{ {
cp(); cp();
event_tree = avl_alloc_tree((avl_compare_t) event_compare, NULL); event_tree = avl_alloc_tree((avl_compare_t) event_compare, (avl_action_t) free_event);
} }
void exit_events(void) void exit_events(void)
@ -57,26 +57,32 @@ void exit_events(void)
avl_delete_tree(event_tree); avl_delete_tree(event_tree);
} }
void flush_events(void) void expire_events(void)
{ {
avl_tree_t *to_flush; avl_node_t *node;
event_t *event; event_t *event;
time_t diff;
/* /*
* Events can be inserted from event handlers, so only flush events * Make all events appear expired by substracting the difference between
* already in the priority queue. * the expiration time of the last event and the current time.
*/ */
cp(); cp();
to_flush = event_tree; if(!event_tree->tail)
init_events(); return;
while (to_flush->head) {
event = to_flush->head->data; event = event_tree->tail->data;
event->handler(event->data); if(event->time < now)
avl_delete(to_flush, event); return;
diff = 1 + event->time - now;
for(node = event_tree->head; node; node = node->next) {
event = node->data;
event->time -= diff;
} }
avl_delete_tree(to_flush);
} }
event_t *new_event(void) event_t *new_event(void)
@ -118,7 +124,7 @@ event_t *get_expired_event(void)
event = event_tree->head->data; event = event_tree->head->data;
if(event->time < now) { if(event->time < now) {
event_del(event); avl_unlink_node(event_tree, event_tree->head);
return event; return event;
} }
} }

View file

@ -38,7 +38,7 @@ typedef struct {
extern void init_events(void); extern void init_events(void);
extern void exit_events(void); extern void exit_events(void);
extern void flush_events(void); extern void expire_events(void);
extern event_t *new_event(void) __attribute__ ((__malloc__)); extern event_t *new_event(void) __attribute__ ((__malloc__));
extern void free_event(event_t *); extern void free_event(event_t *);
extern void event_add(event_t *); extern void event_add(event_t *);

View file

@ -423,18 +423,17 @@ int main_loop(void)
} }
} }
if(sigalrm) {
logger(LOG_INFO, _("Flushing event queue"));
expire_events();
sigalrm = false;
}
while((event = get_expired_event())) { while((event = get_expired_event())) {
event->handler(event->data); event->handler(event->data);
free_event(event); free_event(event);
} }
if(sigalrm) {
logger(LOG_INFO, _("Flushing event queue"));
flush_events();
sigalrm = false;
}
if(sighup) { if(sighup) {
connection_t *c; connection_t *c;
avl_node_t *node; avl_node_t *node;