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:
parent
32dbe2d298
commit
08eb25f53a
30
serialport.c
30
serialport.c
@ -64,17 +64,12 @@ struct time {
|
||||
};
|
||||
|
||||
struct timeout {
|
||||
unsigned int ms;
|
||||
struct time start, delta, now, end;
|
||||
unsigned int ms, limit_ms;
|
||||
struct time start, now, end, delta, delta_max;
|
||||
struct timeval delta_tv;
|
||||
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)
|
||||
{
|
||||
#ifdef HAVE_CLOCK_GETTIME
|
||||
@ -132,14 +127,21 @@ 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);
|
||||
/* 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)
|
||||
@ -149,8 +151,9 @@ static bool timeout_check(struct timeout *timeout)
|
||||
|
||||
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;
|
||||
if (timeout->limit_ms)
|
||||
if ((timeout->overflow = time_greater(&timeout->delta, &timeout->delta_max)))
|
||||
timeout->delta = timeout->delta_max;
|
||||
|
||||
return time_greater(&timeout->now, &timeout->end);
|
||||
}
|
||||
@ -169,8 +172,8 @@ static unsigned int timeout_remaining_ms(struct timeout *timeout)
|
||||
{
|
||||
if (timeout->ms == 0)
|
||||
return -1;
|
||||
else if (timeout->overflow)
|
||||
return INT_MAX;
|
||||
else if (timeout->limit_ms && timeout->overflow)
|
||||
return timeout->limit_ms;
|
||||
else
|
||||
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_limit(&timeout, INT_MAX);
|
||||
|
||||
/* Loop until an event occurs. */
|
||||
while (1) {
|
||||
|
Loading…
Reference in New Issue
Block a user