aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2009-01-02 23:57:22 +0000
committerHarald Welte <laforge@gnumonks.org>2009-01-02 23:57:22 +0000
commitb8f04ea5a90ca79449e26c8c30a245f1cd34c0cf (patch)
tree17e54a27eb16b5daf1b19fd5fa98234c842953a1
parent219518d06492d867909d91f1512f50d3235e1cc8 (diff)
Add new management function to struct timer_list
Make sure that del_timer succeeds and removes an entry from the list. Currently sending the LOCATION UPDATING REJECT from within the timer will not remove the list element as ->active gets set to 0 in the timer updating before calling the callback. Fix the segfault and allow the timer to be removed from within its own callback.
-rw-r--r--include/openbsc/timer.h3
-rw-r--r--src/timer.c6
2 files changed, 6 insertions, 3 deletions
diff --git a/include/openbsc/timer.h b/include/openbsc/timer.h
index e8dc91a84..b3e809e79 100644
--- a/include/openbsc/timer.h
+++ b/include/openbsc/timer.h
@@ -1,5 +1,5 @@
/*
- * (C) 2008 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2008, 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -46,6 +46,7 @@ struct timer_list {
struct timeval timeout;
int active : 1;
int handled : 1;
+ int in_list : 1;
void (*cb)(void*);
void *data;
diff --git a/src/timer.c b/src/timer.c
index 158ee76b7..d2039fd10 100644
--- a/src/timer.c
+++ b/src/timer.c
@@ -1,5 +1,5 @@
/*
- * (C) 2008 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2008,2009 by Holger Hans Peter Freyther <zecke@selfish.org>
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -43,6 +43,7 @@ void add_timer(struct timer_list *timer)
if (timer == list_timer)
return;
+ timer->in_list = 1;
llist_add(&timer->entry, &timer_list);
}
@@ -60,8 +61,9 @@ void schedule_timer(struct timer_list *timer, int seconds, int microseconds)
void del_timer(struct timer_list *timer)
{
- if (timer_pending(timer)) {
+ if (timer->in_list) {
timer->active = 0;
+ timer->in_list = 0;
llist_del(&timer->entry);
}
}