1
0
mirror of git://sigrok.org/libserialport synced 2023-08-10 21:13:24 +03:00

More generic solution for limiting per-call timeout.

This commit is contained in:
Martin Ling 2020-01-03 23:33:48 +00:00
parent 32dbe2d298
commit 08eb25f53a

View File

@ -64,17 +64,12 @@ struct time {
}; };
struct timeout { struct timeout {
unsigned int ms; unsigned int ms, limit_ms;
struct time start, delta, now, end; struct time start, now, end, delta, delta_max;
struct timeval delta_tv; struct timeval delta_tv;
bool overflow; bool overflow;
}; };
#define TIME_ZERO {.tv = {0, 0}}
#define TIME_MS(ms) {.tv = {ms / 1000, (ms % 1000) * 1000}}
const struct time max_delta = TIME_MS(INT_MAX);
static void time_get(struct time *time) static void time_get(struct time *time)
{ {
#ifdef HAVE_CLOCK_GETTIME #ifdef HAVE_CLOCK_GETTIME
@ -132,14 +127,21 @@ static void timeout_start(struct timeout *timeout, unsigned int timeout_ms)
{ {
timeout->ms = timeout_ms; timeout->ms = timeout_ms;
timeout->overflow = (timeout->ms > INT_MAX);
/* Get time at start of operation. */ /* Get time at start of operation. */
time_get(&timeout->start); time_get(&timeout->start);
/* Define duration of timeout. */ /* Define duration of timeout. */
time_set_ms(&timeout->delta, timeout_ms); time_set_ms(&timeout->delta, timeout_ms);
/* Calculate time at which we should give up. */ /* Calculate time at which we should give up. */
time_add(&timeout->start, &timeout->delta, &timeout->end); time_add(&timeout->start, &timeout->delta, &timeout->end);
/* Disable limit unless timeout_limit() called. */
timeout->limit_ms = 0;
}
static void timeout_limit(struct timeout *timeout, unsigned int limit_ms)
{
timeout->limit_ms = limit_ms;
timeout->overflow = (timeout->ms > timeout->limit_ms);
time_set_ms(&timeout->delta_max, timeout->limit_ms);
} }
static bool timeout_check(struct timeout *timeout) static bool timeout_check(struct timeout *timeout)
@ -149,8 +151,9 @@ static bool timeout_check(struct timeout *timeout)
time_get(&timeout->now); time_get(&timeout->now);
time_sub(&timeout->end, &timeout->now, &timeout->delta); time_sub(&timeout->end, &timeout->now, &timeout->delta);
if ((timeout->overflow = time_greater(&timeout->delta, &max_delta))) if (timeout->limit_ms)
timeout->delta = max_delta; if ((timeout->overflow = time_greater(&timeout->delta, &timeout->delta_max)))
timeout->delta = timeout->delta_max;
return time_greater(&timeout->now, &timeout->end); return time_greater(&timeout->now, &timeout->end);
} }
@ -169,8 +172,8 @@ static unsigned int timeout_remaining_ms(struct timeout *timeout)
{ {
if (timeout->ms == 0) if (timeout->ms == 0)
return -1; return -1;
else if (timeout->overflow) else if (timeout->limit_ms && timeout->overflow)
return INT_MAX; return timeout->limit_ms;
else else
return time_as_ms(&timeout->delta); return time_as_ms(&timeout->delta);
} }
@ -1570,6 +1573,7 @@ SP_API enum sp_return sp_wait(struct sp_event_set *event_set,
} }
timeout_start(&timeout, timeout_ms); timeout_start(&timeout, timeout_ms);
timeout_limit(&timeout, INT_MAX);
/* Loop until an event occurs. */ /* Loop until an event occurs. */
while (1) { while (1) {