diff options
| author | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2008-04-07 00:24:26 +0000 | 
|---|---|---|
| committer | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2008-04-07 00:24:26 +0000 | 
| commit | 66c6b4d3b3905bb868694e9681e83c18eece729e (patch) | |
| tree | 85b008117da89aa41652da26422fc2e8c4dd1a66 /package/broadcom-wl | |
| parent | 29c37a46475dd9e4235a3f16f2840db47f5e27aa (diff) | |
add timer fix by mmp from http://forum.openwrt.org/viewtopic.php?id=14841
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@10750 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'package/broadcom-wl')
| -rw-r--r-- | package/broadcom-wl/patches/100-timer_fix.patch | 53 | 
1 files changed, 53 insertions, 0 deletions
| diff --git a/package/broadcom-wl/patches/100-timer_fix.patch b/package/broadcom-wl/patches/100-timer_fix.patch new file mode 100644 index 000000000..c3d9f63bb --- /dev/null +++ b/package/broadcom-wl/patches/100-timer_fix.patch @@ -0,0 +1,53 @@ +Index: broadcom-wl-4.150.10.5.2/router/shared/linux_timer.c +=================================================================== +--- broadcom-wl-4.150.10.5.2.orig/router/shared/linux_timer.c	2008-04-07 00:15:24.914329846 +0200 ++++ broadcom-wl-4.150.10.5.2/router/shared/linux_timer.c	2008-04-07 00:14:52.288470602 +0200 +@@ -94,6 +94,7 @@ + #define TFLAG_NONE	0 + #define TFLAG_CANCELLED	(1<<0) + #define TFLAG_DELETED	(1<<1) ++#define TFLAG_QUEUED	(1<<2) +  + struct event { +     struct timeval it_interval; +@@ -207,6 +208,7 @@ +  + 	event_freelist = event->next; + 	event->next = NULL; ++	event->flags &= ~TFLAG_QUEUED; +  + 	check_event_queue(); +  +@@ -387,6 +389,7 @@ + 	} +  + 	event->flags &= ~TFLAG_CANCELLED; ++	event->flags |= TFLAG_QUEUED; +  + 	unblock_timer(); +  +@@ -502,7 +505,15 @@ + 		(*(event->func))((timer_t) event, (int)event->arg); +  + 		/* If the event has been cancelled, do NOT put it back on the queue. */ +-		if (!(event->flags & TFLAG_CANCELLED)) { ++		/* Check for TFLAG_QUEUED is to avoid pathologic case, when after ++		 * dequeueing event handler deletes its own timer and allocates new one ++		 * which (at least in some cases) gets the same pointer and thus its ++		 * 'flags' will be rewritten, most notably TFLAG_CANCELLED, and, to ++		 * complete the disaster, it will be queued. alarm_handler tries to ++		 * enqueue 'event' (which is on the same memory position as newly ++		 * allocated timer), which results in queueing the same pointer once ++		 * more. And this way, loop in event queue is created. */ ++		if ( !(event->flags & TFLAG_CANCELLED) && !(event->flags & TFLAG_QUEUED) ) { +  + 			/* if the event is a recurring event, reset the timer and + 			 * find its correct place in the sorted list of events. +@@ -545,6 +556,7 @@ + 				/* link our new event into the pending event queue. */ + 				event->next = *ppevent; + 				*ppevent = event; ++				event->flags |= TFLAG_QUEUED; + 			} else { + 				/* there is no interval, so recycle the event structure. + 				 * timer_delete((timer_t) event); | 
