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 {
|
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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user