make timeouts usable reliably from outside of the timeout routine

although timeouts are relative to timeouts_last_time (transitively by
addition to the time values of their predecessors, if there are any),
sys_timeout does not compensate for that; as a result, timeouts fire too
early unless invoked from within a timeout handler (when
timeouts_last_time == now).
This commit is contained in:
chrysn 2013-11-21 08:37:39 +01:00 committed by Simon Goldschmidt
parent f311045320
commit 252abbeb8d

View File

@ -326,16 +326,26 @@ sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg)
#endif /* LWIP_DEBUG_TIMERNAMES */ #endif /* LWIP_DEBUG_TIMERNAMES */
{ {
struct sys_timeo *timeout, *t; struct sys_timeo *timeout, *t;
u32_t now, diff;
timeout = (struct sys_timeo *)memp_malloc(MEMP_SYS_TIMEOUT); timeout = (struct sys_timeo *)memp_malloc(MEMP_SYS_TIMEOUT);
if (timeout == NULL) { if (timeout == NULL) {
LWIP_ASSERT("sys_timeout: timeout != NULL, pool MEMP_SYS_TIMEOUT is empty", timeout != NULL); LWIP_ASSERT("sys_timeout: timeout != NULL, pool MEMP_SYS_TIMEOUT is empty", timeout != NULL);
return; return;
} }
now = sys_now();
if (next_timeout == NULL) {
diff = 0;
timeouts_last_time = now;
} else {
diff = now - timeouts_last_time;
}
timeout->next = NULL; timeout->next = NULL;
timeout->h = handler; timeout->h = handler;
timeout->arg = arg; timeout->arg = arg;
timeout->time = msecs; timeout->time = msecs + diff;
#if LWIP_DEBUG_TIMERNAMES #if LWIP_DEBUG_TIMERNAMES
timeout->handler_name = handler_name; timeout->handler_name = handler_name;
LWIP_DEBUGF(TIMERS_DEBUG, ("sys_timeout: %p msecs=%"U32_F" handler=%s arg=%p\n", LWIP_DEBUGF(TIMERS_DEBUG, ("sys_timeout: %p msecs=%"U32_F" handler=%s arg=%p\n",
@ -437,7 +447,7 @@ sys_check_timeouts(void)
if (tmptimeout && (tmptimeout->time <= diff)) { if (tmptimeout && (tmptimeout->time <= diff)) {
/* timeout has expired */ /* timeout has expired */
had_one = 1; had_one = 1;
timeouts_last_time = now; timeouts_last_time += tmptimeout->time;
diff -= tmptimeout->time; diff -= tmptimeout->time;
next_timeout = tmptimeout->next; next_timeout = tmptimeout->next;
handler = tmptimeout->h; handler = tmptimeout->h;