/* * Check if and when lwIP has its next timeout, and set or cancel our timer * accordingly. */ static void set_lwip_timer(void) { uint32_t next_timeout; clock_t ticks; /* Ask lwIP when the next alarm is supposed to go off, if any. */ next_timeout = sys_timeouts_sleeptime(); /* * Set or update the lwIP timer. We rely on set_timer() asking the * kernel for an alarm only if the timeout is different from the one we * gave it last time (if at all). However, due to conversions between * absolute and relative times, and the fact that we cannot guarantee * that the uptime itself does not change while executing these * routines, set_timer() will sometimes be issuing a kernel call even * if the alarm has not changed. Not a huge deal, but fixing this will * require a different interface to lwIP and/or the timers library. */ if (next_timeout != (uint32_t)-1) { /* * Round up the next timeout (which is in milliseconds) to the * number of clock ticks to add to the current time. Avoid any * potential for overflows, no matter how unrealistic.. */ if (next_timeout > TMRDIFF_MAX / sys_hz()) ticks = TMRDIFF_MAX; else ticks = (next_timeout * sys_hz() + 999) / 1000; set_timer(&lwip_timer, ticks, expire_lwip_timer, 0 /*unused*/); } else cancel_timer(&lwip_timer); /* not really needed.. */ }
/** * Wait (forever) for a message to arrive in an mbox. * While waiting, timeouts are processed. * * @param mbox the mbox to fetch the message from * @param msg the place to store the message */ void sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg) { u32_t sleeptime; again: if (!next_timeout) { sys_arch_mbox_fetch(mbox, msg, 0); return; } sleeptime = sys_timeouts_sleeptime(); if (sleeptime == 0 || sys_arch_mbox_fetch(mbox, msg, sleeptime) == SYS_ARCH_TIMEOUT) { /* If a SYS_ARCH_TIMEOUT value is returned, a timeout occurred before a message could be fetched. */ sys_check_timeouts(); /* We try again to fetch a message from the mbox. */ goto again; } }