+static void timeout_start(struct timeout *timeout, unsigned int timeout_ms)
+{
+ timeout->ms = timeout_ms;
+
+ timeout->overflow = (timeout->ms > INT_MAX);
+
+ /* Get time at start of operation. */
+ time_get(&timeout->start);
+ /* Define duration of timeout. */
+ time_set_ms(&timeout->delta, timeout_ms);
+ /* Calculate time at which we should give up. */
+ time_add(&timeout->start, &timeout->delta, &timeout->end);
+}
+
+static bool timeout_check(struct timeout *timeout)
+{
+ if (timeout->ms == 0)
+ return false;
+
+ time_get(&timeout->now);
+ time_sub(&timeout->end, &timeout->now, &timeout->delta);
+ if ((timeout->overflow = time_greater(&timeout->delta, &max_delta)))
+ timeout->delta = max_delta;
+
+ return time_greater(&timeout->now, &timeout->end);
+}
+
+static struct timeval *timeout_timeval(struct timeout *timeout)
+{
+ if (timeout->ms == 0)
+ return NULL;
+
+ time_as_timeval(&timeout->delta, &timeout->delta_tv);
+
+ return &timeout->delta_tv;
+}
+
+static unsigned int timeout_remaining_ms(struct timeout *timeout)
+{
+ if (timeout->ms == 0)
+ return -1;
+ else if (timeout->overflow)
+ return INT_MAX;
+ else
+ return time_as_ms(&timeout->delta);
+}
+