diff --git a/CHANGELOG b/CHANGELOG index 8f0f5ba3..77da0cff 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -198,6 +198,10 @@ HISTORY ++ Bugfixes: + 2010-05-05: Simon Goldschmidt + * def.h, timers.c: Fixed bug #29769 (sys_check_timeouts: sys_now() may + overflow) + 2010-04-21: Simon Goldschmidt * api_msg.c: Fixed bug #29617 (sometime cause stall on delete listening connection) diff --git a/src/core/timers.c b/src/core/timers.c index 433e4adb..0dba9272 100644 --- a/src/core/timers.c +++ b/src/core/timers.c @@ -370,8 +370,8 @@ sys_check_timeouts(void) now = sys_now(); if (next_timeout) { - /* @todo: wrap around? */ - diff = now - timeouts_last_time; + /* this cares for wraparounds */ + diff = LWIP_U32_DIFF(now, timeouts_last_time); do { had_one = 0; diff --git a/src/include/lwip/def.h b/src/include/lwip/def.h index 52d511af..cda5d820 100644 --- a/src/include/lwip/def.h +++ b/src/include/lwip/def.h @@ -47,6 +47,11 @@ extern "C" { #define NULL ((void *)0) #endif +/** Get the absolute difference between 2 u32_t values (correcting overflows) + * 'a' is expected to be 'higher' (without overflow) than 'b'. */ +#define LWIP_U32_DIFF(a, b) (((a) >= (b)) ? ((a) - (b)) : (((a) + ((b) ^ 0xFFFFFFFF) + 1))) + +/* Endianess-optimized shifting of two u8_t to create one u16_t */ #if BYTE_ORDER == LITTLE_ENDIAN #define LWIP_MAKE_U16(a, b) ((a << 8) | b) #else