gluon-neighbour-info: simplify and fix timeout calculation
The timeout was calculated incorrectly (in each iteration the span between the start time and the current time was substracted from the timeout again), and would often become negative, causing warnings in the kernel log.
This commit is contained in:
parent
a3155c427a
commit
fa504dae8d
@ -58,7 +58,7 @@ void getclock(struct timeval *tv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Assumes a and b are normalized */
|
/* Assumes a and b are normalized */
|
||||||
void tv_subtract (struct timeval *r, struct timeval *a, struct timeval *b) {
|
void tv_subtract (struct timeval *r, const struct timeval *a, const struct timeval *b) {
|
||||||
r->tv_usec = a->tv_usec - b->tv_usec;
|
r->tv_usec = a->tv_usec - b->tv_usec;
|
||||||
r->tv_sec = a->tv_sec - b->tv_sec;
|
r->tv_sec = a->tv_sec - b->tv_sec;
|
||||||
|
|
||||||
@ -68,18 +68,17 @@ void tv_subtract (struct timeval *r, struct timeval *a, struct timeval *b) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t recvtimeout(int socket, void *buffer, size_t length, int flags, struct timeval *timeout, struct timeval *offset) {
|
ssize_t recvtimeout(int socket, void *buffer, size_t length, int flags, const struct timeval *timeout) {
|
||||||
struct timeval now, delta;
|
struct timeval now, timeout_left;
|
||||||
ssize_t ret;
|
|
||||||
|
|
||||||
setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, timeout, sizeof(*timeout));
|
|
||||||
ret = recv(socket, buffer, length, flags);
|
|
||||||
|
|
||||||
getclock(&now);
|
getclock(&now);
|
||||||
tv_subtract(&delta, &now, offset);
|
tv_subtract(&timeout_left, timeout, &now);
|
||||||
tv_subtract(timeout, timeout, &delta);
|
|
||||||
|
|
||||||
return ret;
|
if (timeout_left.tv_sec < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &timeout_left, sizeof(timeout_left));
|
||||||
|
return recv(socket, buffer, length, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
int request(const int sock, const struct sockaddr_in6 *client_addr, const char *request, const char *sse, double timeout, unsigned int max_count) {
|
int request(const int sock, const struct sockaddr_in6 *client_addr, const char *request, const char *sse, double timeout, unsigned int max_count) {
|
||||||
@ -94,14 +93,18 @@ int request(const int sock, const struct sockaddr_in6 *client_addr, const char *
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct timeval tv_timeout, tv_offset;
|
struct timeval tv_timeout;
|
||||||
tv_timeout.tv_sec = (int) timeout;
|
getclock(&tv_timeout);
|
||||||
tv_timeout.tv_usec = ((int) (timeout * 1000000)) % 1000000;
|
|
||||||
|
|
||||||
getclock(&tv_offset);
|
tv_timeout.tv_sec += (int) timeout;
|
||||||
|
tv_timeout.tv_usec += ((int) (timeout * 1000000)) % 1000000;
|
||||||
|
if (tv_timeout.tv_usec >= 1000000) {
|
||||||
|
tv_timeout.tv_usec -= 1000000;
|
||||||
|
tv_timeout.tv_sec += 1;
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ret = recvtimeout(sock, buffer, sizeof(buffer), 0, &tv_timeout, &tv_offset);
|
ret = recvtimeout(sock, buffer, sizeof(buffer), 0, &tv_timeout);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
break;
|
break;
|
||||||
@ -176,6 +179,10 @@ int main(int argc, char **argv) {
|
|||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
timeout = atof(optarg);
|
timeout = atof(optarg);
|
||||||
|
if (timeout < 0) {
|
||||||
|
perror("Negative timeout not supported");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
sse = optarg;
|
sse = optarg;
|
||||||
|
Loading…
Reference in New Issue
Block a user