1 Index: broadcom-wl-4.150.10.5.2/router/shared/linux_timer.c
2 ===================================================================
3 --- broadcom-wl-4.150.10.5.2.orig/router/shared/linux_timer.c 2008-04-07 00:15:24.914329846 +0200
4 +++ broadcom-wl-4.150.10.5.2/router/shared/linux_timer.c 2008-04-07 00:14:52.288470602 +0200
7 #define TFLAG_CANCELLED (1<<0)
8 #define TFLAG_DELETED (1<<1)
9 +#define TFLAG_QUEUED (1<<2)
12 struct timeval it_interval;
15 event_freelist = event->next;
17 + event->flags &= ~TFLAG_QUEUED;
24 event->flags &= ~TFLAG_CANCELLED;
25 + event->flags |= TFLAG_QUEUED;
30 (*(event->func))((timer_t) event, (int)event->arg);
32 /* If the event has been cancelled, do NOT put it back on the queue. */
33 - if (!(event->flags & TFLAG_CANCELLED)) {
34 + /* Check for TFLAG_QUEUED is to avoid pathologic case, when after
35 + * dequeueing event handler deletes its own timer and allocates new one
36 + * which (at least in some cases) gets the same pointer and thus its
37 + * 'flags' will be rewritten, most notably TFLAG_CANCELLED, and, to
38 + * complete the disaster, it will be queued. alarm_handler tries to
39 + * enqueue 'event' (which is on the same memory position as newly
40 + * allocated timer), which results in queueing the same pointer once
41 + * more. And this way, loop in event queue is created. */
42 + if ( !(event->flags & TFLAG_CANCELLED) && !(event->flags & TFLAG_QUEUED) ) {
44 /* if the event is a recurring event, reset the timer and
45 * find its correct place in the sorted list of events.
47 /* link our new event into the pending event queue. */
48 event->next = *ppevent;
50 + event->flags |= TFLAG_QUEUED;
52 /* there is no interval, so recycle the event structure.
53 * timer_delete((timer_t) event);