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.

diff --git a/include/openbsc/timer.h b/include/openbsc/timer.h
index e8dc91a..b3e809e 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 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 158ee76..d2039fd 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 @@
 		if (timer == list_timer)
 			return;
 
+	timer->in_list = 1;
 	llist_add(&timer->entry, &timer_list);
 }
 
@@ -60,8 +61,9 @@
 
 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);
 	}
 }