[retry] Use a separate flag to indicate that a retry timer is running
Using start==0 to indicate a stopped timer is dangerous, because 0 is a valid value for the current tick counter.
This commit is contained in:
parent
941b4c2adb
commit
f945d6d201
|
@ -19,6 +19,8 @@
|
||||||
struct retry_timer {
|
struct retry_timer {
|
||||||
/** List of active timers */
|
/** List of active timers */
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
/** Timer is currently running */
|
||||||
|
unsigned int running;
|
||||||
/** Timeout value (in ticks) */
|
/** Timeout value (in ticks) */
|
||||||
unsigned long timeout;
|
unsigned long timeout;
|
||||||
/** Minimum timeout value (in ticks)
|
/** Minimum timeout value (in ticks)
|
||||||
|
@ -31,10 +33,7 @@ struct retry_timer {
|
||||||
* A value of zero means "use default timeout."
|
* A value of zero means "use default timeout."
|
||||||
*/
|
*/
|
||||||
unsigned long max_timeout;
|
unsigned long max_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;
|
||||||
|
@ -74,7 +73,7 @@ static inline void start_timer_nodelay ( struct retry_timer *timer ) {
|
||||||
*/
|
*/
|
||||||
static inline __attribute__ (( always_inline )) unsigned long
|
static inline __attribute__ (( always_inline )) unsigned long
|
||||||
timer_running ( struct retry_timer *timer ) {
|
timer_running ( struct retry_timer *timer ) {
|
||||||
return ( timer->start );
|
return ( timer->running );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _GPXE_RETRY_H */
|
#endif /* _GPXE_RETRY_H */
|
||||||
|
|
|
@ -55,9 +55,10 @@ 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_running ( timer ) )
|
if ( ! timer->running )
|
||||||
list_add ( &timer->list, &timers );
|
list_add ( &timer->list, &timers );
|
||||||
timer->start = currticks();
|
timer->start = currticks();
|
||||||
|
timer->running = 1;
|
||||||
|
|
||||||
/* 0 means "use default timeout" */
|
/* 0 means "use default timeout" */
|
||||||
if ( timer->min_timeout == 0 )
|
if ( timer->min_timeout == 0 )
|
||||||
|
@ -82,6 +83,8 @@ void start_timer ( struct retry_timer *timer ) {
|
||||||
void start_timer_fixed ( struct retry_timer *timer, unsigned long timeout ) {
|
void start_timer_fixed ( struct retry_timer *timer, unsigned long timeout ) {
|
||||||
start_timer ( timer );
|
start_timer ( timer );
|
||||||
timer->timeout = timeout;
|
timer->timeout = timeout;
|
||||||
|
DBG2 ( "Timer %p expiry time changed to %ld\n",
|
||||||
|
timer, ( timer->start + timer->timeout ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,12 +100,12 @@ void stop_timer ( struct retry_timer *timer ) {
|
||||||
unsigned long runtime;
|
unsigned long runtime;
|
||||||
|
|
||||||
/* If timer was already stopped, do nothing */
|
/* If timer was already stopped, do nothing */
|
||||||
if ( ! timer_running ( timer ) )
|
if ( ! timer->running )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
list_del ( &timer->list );
|
list_del ( &timer->list );
|
||||||
runtime = ( now - timer->start );
|
runtime = ( now - timer->start );
|
||||||
timer->start = 0;
|
timer->running = 0;
|
||||||
DBG2 ( "Timer %p stopped at time %ld (ran for %ld)\n",
|
DBG2 ( "Timer %p stopped at time %ld (ran for %ld)\n",
|
||||||
timer, now, runtime );
|
timer, now, runtime );
|
||||||
|
|
||||||
|
@ -144,8 +147,9 @@ static void timer_expired ( struct retry_timer *timer ) {
|
||||||
/* Stop timer without performing RTT calculations */
|
/* Stop timer without performing RTT calculations */
|
||||||
DBG2 ( "Timer %p stopped at time %ld on expiry\n",
|
DBG2 ( "Timer %p stopped at time %ld on expiry\n",
|
||||||
timer, currticks() );
|
timer, currticks() );
|
||||||
|
assert ( timer->running );
|
||||||
list_del ( &timer->list );
|
list_del ( &timer->list );
|
||||||
timer->start = 0;
|
timer->running = 0;
|
||||||
timer->count++;
|
timer->count++;
|
||||||
|
|
||||||
/* Back off the timeout value */
|
/* Back off the timeout value */
|
||||||
|
|
Reference in New Issue