title: Infinite loop at sys_timeout() - LWIC/src/core/timeouts.c
body: <p>In a Ethernet application, when the communication with the server get lost for nearly 10 minutes, the code gets in a infinite loop at line 244:</p>
  
  <p><code>if (t-&gt;next == NULL || t-&gt;next-&gt;time &gt; timeout-&gt;time)</code> </p>
  
  <p>is never true.</p>
  
  <p>Here's the loop:</p>
  
  <pre><code>void
  sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg)
  #endif /* LWIP_DEBUG_TIMERNAMES */
  {
    struct sys_timeo *timeout, *t;
    u32_t now, diff;
  
    timeout = (struct sys_timeo *)memp_malloc(MEMP_SYS_TIMEOUT);
    if (timeout == NULL) {
      LWIP_ASSERT("sys_timeout: timeout != NULL, pool MEMP_SYS_TIMEOUT is empty", timeout != NULL);
      return;
    }
  
    now = sys_now();
    if (next_timeout == NULL) {
      diff = 0;
      timeouts_last_time = now;
    } else {
      diff = now - timeouts_last_time;
    }
  
    timeout-&gt;next = NULL;
    timeout-&gt;h = handler;
    timeout-&gt;arg = arg;
    timeout-&gt;time = msecs + diff;
  #if LWIP_DEBUG_TIMERNAMES
    timeout-&gt;handler_name = handler_name;
    LWIP_DEBUGF(TIMERS_DEBUG, ("sys_timeout: %p msecs=%"U32_F" handler=%s arg=%p\n",
      (void *)timeout, msecs, handler_name, (void *)arg));
  #endif /* LWIP_DEBUG_TIMERNAMES */
  
    if (next_timeout == NULL) {
      next_timeout = timeout;
      return;
    }
  
    if (next_timeout-&gt;time &gt; msecs) {
      next_timeout-&gt;time -= msecs;
      timeout-&gt;next = next_timeout;
      next_timeout = timeout;
    } else {
      for (t = next_timeout; t != NULL; t = t-&gt;next) {
        timeout-&gt;time -= t-&gt;time;
        if (t-&gt;next == NULL || t-&gt;next-&gt;time &gt; timeout-&gt;time) {
          if (t-&gt;next != NULL) {
            t-&gt;next-&gt;time -= timeout-&gt;time;
          } else if (timeout-&gt;time &gt; msecs) {
            /* If this is the case, 'timeouts_last_time' and 'now' differs too much.
               This can be due to sys_check_timeouts() not being called at the right
               times, but also when stopping in a breakpoint. Anyway, let's assume
               this is not wanted, so add the first timer's time instead of 'diff' */
            timeout-&gt;time = msecs + next_timeout-&gt;time;
          }
          timeout-&gt;next = t-&gt;next;
          t-&gt;next = timeout;
          break;
        }
      }
    }
  }
  </code></pre>