david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

Make start_timer() and stop_timer() robust against incorrect usage.

This commit is contained in:
Michael Brown 2006-12-22 01:35:21 +00:00
parent 9485478acc
commit 66a7ed23cb
2 changed files with 12 additions and 2 deletions

View File

@ -15,7 +15,10 @@ struct retry_timer {
struct list_head list; struct list_head list;
/** Timeout value (in ticks) */ /** Timeout value (in ticks) */
unsigned long timeout; unsigned long timeout;
/** Start time (in ticks) */ /** Start time (in ticks)
*
* A start time of zero indicates a stopped timer.
*/
unsigned long start; unsigned long start;
/** Retry count */ /** Retry count */
unsigned int count; unsigned int count;

View File

@ -64,10 +64,11 @@ static LIST_HEAD ( timers );
* be stopped and the timer's callback function will be called. * be stopped and the timer's callback function will be called.
*/ */
void start_timer ( struct retry_timer *timer ) { void start_timer ( struct retry_timer *timer ) {
if ( ! timer->start )
list_add ( &timer->list, &timers );
timer->start = currticks(); timer->start = currticks();
if ( timer->timeout < MIN_TIMEOUT ) if ( timer->timeout < MIN_TIMEOUT )
timer->timeout = MIN_TIMEOUT; timer->timeout = MIN_TIMEOUT;
list_add ( &timer->list, &timers );
DBG2 ( "Timer %p started\n", timer ); DBG2 ( "Timer %p started\n", timer );
} }
@ -82,9 +83,14 @@ void stop_timer ( struct retry_timer *timer ) {
unsigned long old_timeout = timer->timeout; unsigned long old_timeout = timer->timeout;
unsigned long runtime; unsigned long runtime;
/* If timer was already stopped, do nothing */
if ( ! timer->start )
return;
DBG2 ( "Timer %p stopped\n", timer ); DBG2 ( "Timer %p stopped\n", timer );
list_del ( &timer->list ); list_del ( &timer->list );
runtime = currticks() - timer->start; runtime = currticks() - timer->start;
timer->start = 0;
/* Update timer. Variables are: /* Update timer. Variables are:
* *
@ -124,6 +130,7 @@ static void timer_expired ( struct retry_timer *timer ) {
/* Stop timer without performing RTT calculations */ /* Stop timer without performing RTT calculations */
DBG2 ( "Timer %p stopped on expiry\n", timer ); DBG2 ( "Timer %p stopped on expiry\n", timer );
list_del ( &timer->list ); list_del ( &timer->list );
timer->start = 0;
timer->count++; timer->count++;
/* Back off the timeout value */ /* Back off the timeout value */