From 66a7ed23cb3fbfea574b79d3ca4aed9f626c6e3f Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 22 Dec 2006 01:35:21 +0000 Subject: [PATCH] Make start_timer() and stop_timer() robust against incorrect usage. --- src/include/gpxe/retry.h | 5 ++++- src/net/retry.c | 9 ++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/include/gpxe/retry.h b/src/include/gpxe/retry.h index 7291db23..57be432e 100644 --- a/src/include/gpxe/retry.h +++ b/src/include/gpxe/retry.h @@ -15,7 +15,10 @@ struct retry_timer { struct list_head list; /** Timeout value (in ticks) */ unsigned long timeout; - /** Start time (in ticks) */ + /** Start time (in ticks) + * + * A start time of zero indicates a stopped timer. + */ unsigned long start; /** Retry count */ unsigned int count; diff --git a/src/net/retry.c b/src/net/retry.c index 0fb47952..3d9fb989 100644 --- a/src/net/retry.c +++ b/src/net/retry.c @@ -64,10 +64,11 @@ static LIST_HEAD ( timers ); * be stopped and the timer's callback function will be called. */ void start_timer ( struct retry_timer *timer ) { + if ( ! timer->start ) + list_add ( &timer->list, &timers ); timer->start = currticks(); if ( timer->timeout < MIN_TIMEOUT ) timer->timeout = MIN_TIMEOUT; - list_add ( &timer->list, &timers ); 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 runtime; + /* If timer was already stopped, do nothing */ + if ( ! timer->start ) + return; + DBG2 ( "Timer %p stopped\n", timer ); list_del ( &timer->list ); runtime = currticks() - timer->start; + timer->start = 0; /* Update timer. Variables are: * @@ -124,6 +130,7 @@ static void timer_expired ( struct retry_timer *timer ) { /* Stop timer without performing RTT calculations */ DBG2 ( "Timer %p stopped on expiry\n", timer ); list_del ( &timer->list ); + timer->start = 0; timer->count++; /* Back off the timeout value */