[retry] Use a separate flag to indicate that a retry timer is running
authorMichael Brown <mcb30@etherboot.org>
Sun, 12 Oct 2008 14:04:37 +0000 (15:04 +0100)
committerMichael Brown <mcb30@etherboot.org>
Sun, 12 Oct 2008 14:11:20 +0000 (15:11 +0100)
Using start==0 to indicate a stopped timer is dangerous, because 0 is a
valid value for the current tick counter.

src/include/gpxe/retry.h
src/net/retry.c

index ec57db9..1e7fde4 100644 (file)
@@ -19,6 +19,8 @@
 struct retry_timer {
        /** List of active timers */
        struct list_head list;
+       /** Timer is currently running */
+       unsigned int running;
        /** Timeout value (in ticks) */
        unsigned long timeout;
        /** Minimum timeout value (in ticks)
@@ -31,10 +33,7 @@ struct retry_timer {
         * A value of zero means "use default timeout."
         */
        unsigned long max_timeout;
-       /** Start time (in ticks)
-        *
-        * A start time of zero indicates a stopped timer.
-        */
+       /** Start time (in ticks) */
        unsigned long start;
        /** Retry 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
 timer_running ( struct retry_timer *timer ) {
-       return ( timer->start );
+       return ( timer->running );
 }
 
 #endif /* _GPXE_RETRY_H */
index 2a645c9..cd793a7 100644 (file)
@@ -55,9 +55,10 @@ static LIST_HEAD ( timers );
  * be stopped and the timer's callback function will be called.
  */
 void start_timer ( struct retry_timer *timer ) {
-       if ( ! timer_running ( timer ) )
+       if ( ! timer->running )
                list_add ( &timer->list, &timers );
        timer->start = currticks();
+       timer->running = 1;
 
        /* 0 means "use default timeout" */
        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 ) {
        start_timer ( timer );
        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;
 
        /* If timer was already stopped, do nothing */
-       if ( ! timer_running ( timer ) )
+       if ( ! timer->running )
                return;
 
        list_del ( &timer->list );
        runtime = ( now - timer->start );
-       timer->start = 0;
+       timer->running = 0;
        DBG2 ( "Timer %p stopped at time %ld (ran for %ld)\n",
               timer, now, runtime );
 
@@ -144,8 +147,9 @@ static void timer_expired ( struct retry_timer *timer ) {
        /* Stop timer without performing RTT calculations */
        DBG2 ( "Timer %p stopped at time %ld on expiry\n",
               timer, currticks() );
+       assert ( timer->running );
        list_del ( &timer->list );
-       timer->start = 0;
+       timer->running = 0;
        timer->count++;
 
        /* Back off the timeout value */