Use select() for arbitrary read timeouts

This commit is contained in:
XANTRONIX Development 2017-11-29 20:33:01 -06:00
parent 680e42c8ef
commit f76c017783
10 changed files with 74 additions and 50 deletions

View file

@ -27,7 +27,7 @@ int main(int argc, char **argv) {
goto error_link_open;
}
while (skipstone_link_recv(link, buf, &len, &endpoint) >= 0) {
while (skipstone_link_recv(link, buf, &len, &endpoint, NULL) >= 0) {
printf("Received message %hu bytes for endpoint %hu\n",
len, endpoint);
}

View file

@ -27,7 +27,7 @@ int main(int argc, char **argv) {
goto error_link_open;
}
while (skipstone_link_recv(link, buf, &len, &endpoint) >= 0) {
while (skipstone_link_recv(link, buf, &len, &endpoint, NULL) >= 0) {
printf("Received message %hu bytes for endpoint %hu\n",
len, endpoint);
}

View file

@ -78,14 +78,24 @@ int main(int argc, char **argv) {
skipstone_message_service_register(service, 17, answer_phone_version_message, NULL);
skipstone_message_service_register(service, 32, answer_music_message, NULL);
skipstone_message_service_run(service, link);
while (1) {
struct timeval timeout = {
.tv_sec = 0,
.tv_usec = 50000
};
perror("skipstone_message_service_run()");
if (skipstone_message_service_next_event(service, link, &timeout) < 0) {
perror("skipstone_message_service_next_event()");
goto error_io;
}
}
skipstone_link_close(link);
return 0;
error_io:
error_message_service_new:
skipstone_link_close(link);

View file

@ -78,14 +78,24 @@ int main(int argc, char **argv) {
skipstone_message_service_register(service, 17, answer_phone_version_message, NULL);
skipstone_message_service_register(service, 32, answer_music_message, NULL);
skipstone_message_service_run(service, link);
while (1) {
struct timeval timeout = {
.tv_sec = 0,
.tv_usec = 50000
};
perror("skipstone_message_service_run()");
if (skipstone_message_service_next_event(service, link, &timeout) < 0) {
perror("skipstone_message_service_next_event()");
goto error_io;
}
}
skipstone_link_close(link);
return 0;
error_io:
error_message_service_new:
skipstone_link_close(link);

View file

@ -2,6 +2,7 @@
#define _SKIPSTONE_LINK_H
#include <stdint.h>
#include <sys/time.h>
typedef struct _skipstone_link skipstone_link;
@ -10,9 +11,9 @@ skipstone_link *skipstone_link_open_serial(const char *device);
int skipstone_link_close(skipstone_link *link);
int skipstone_link_send(skipstone_link *link,
void *buf, uint16_t size, uint16_t id);
void *buf, uint16_t size, uint16_t id);
int skipstone_link_recv(skipstone_link *link,
void *buf, uint16_t *size, uint16_t *id);
void *buf, uint16_t *size, uint16_t *id, struct timeval *timeout);
#endif /* _SKIPSTONE_LINK_H */

View file

@ -73,9 +73,6 @@ int skipstone_message_service_queue(skipstone_message_service *service,
skipstone_message *message, uint16_t id);
int skipstone_message_service_next_event(skipstone_message_service *service,
skipstone_link *link);
int skipstone_message_service_run(skipstone_message_service *service,
skipstone_link *link);
skipstone_link *link, struct timeval *timeout);
#endif /* _SKIPSTONE_MESSAGE_H */

View file

@ -6,6 +6,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include "util.h"
#include <skipstone/link.h>
@ -134,12 +135,27 @@ error_toobig:
return -1;
}
int skipstone_link_recv(skipstone_link *link, void *buf, uint16_t *size, uint16_t *id) {
int skipstone_link_recv(skipstone_link *link,
void *buf, uint16_t *size, uint16_t *id, struct timeval *timeout) {
skipstone_message_header header;
ssize_t len_read;
size_t len_wanted, offset = 0;
fd_set fds;
int ready;
FD_ZERO(&fds);
FD_SET(link->serial.fd, &fds);
if ((ready = select(1 + link->serial.fd, &fds, NULL, NULL, timeout)) < 0) {
goto error_io;
}
if (ready == 0) {
return 0;
}
if (read(link->serial.fd, &header, sizeof(header)) < 0) {
goto error_io;
}
@ -162,7 +178,7 @@ int skipstone_link_recv(skipstone_link *link, void *buf, uint16_t *size, uint16_
*size = be16toh(header.size);
*id = be16toh(header.id);
return 0;
return 1;
error_io:
return -1;

View file

@ -6,6 +6,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include "util.h"
#include <skipstone/link.h>
@ -134,12 +135,27 @@ error_toobig:
return -1;
}
int skipstone_link_recv(skipstone_link *link, void *buf, uint16_t *size, uint16_t *id) {
int skipstone_link_recv(skipstone_link *link,
void *buf, uint16_t *size, uint16_t *id, struct timeval *timeout) {
skipstone_message_header header;
ssize_t len_read;
size_t len_wanted, offset = 0;
fd_set fds;
int ready;
FD_ZERO(&fds);
FD_SET(link->serial.fd, &fds);
if ((ready = select(1 + link->serial.fd, &fds, NULL, NULL, timeout)) < 0) {
goto error_io;
}
if (ready == 0) {
return 0;
}
if (read(link->serial.fd, &header, sizeof(header)) < 0) {
goto error_io;
}
@ -162,7 +178,7 @@ int skipstone_link_recv(skipstone_link *link, void *buf, uint16_t *size, uint16_
*size = be16toh(header.size);
*id = be16toh(header.id);
return 0;
return 1;
error_io:
return -1;

View file

@ -298,16 +298,17 @@ error_malloc_packed:
}
int skipstone_message_service_next_event(skipstone_message_service *service,
skipstone_link *link) {
skipstone_link *link, struct timeval *timeout) {
skipstone_message_header *message;
struct endpoint *endpoint;
uint16_t size, id;
int ready;
if (skipstone_link_recv(link, service->buf, &size, &id) < 0) {
if ((ready = skipstone_link_recv(link, service->buf, &size, &id, timeout)) < 0) {
goto error_io;
}
if ((endpoint = skipstone_map_get(service->endpoints, id)) != NULL) {
if (ready && (endpoint = skipstone_map_get(service->endpoints, id)) != NULL) {
if (endpoint->handler(service, service->buf, size, id, endpoint->context) < 0) {
goto error_io;
}
@ -324,17 +325,3 @@ int skipstone_message_service_next_event(skipstone_message_service *service,
error_io:
return -1;
}
int skipstone_message_service_run(skipstone_message_service *service,
skipstone_link *link) {
while (1) {
if (skipstone_message_service_next_event(service, link) < 0) {
goto error_service_next_event;
}
}
return 0;
error_service_next_event:
return -1;
}

View file

@ -298,16 +298,17 @@ error_malloc_packed:
}
int skipstone_message_service_next_event(skipstone_message_service *service,
skipstone_link *link) {
skipstone_link *link, struct timeval *timeout) {
skipstone_message_header *message;
struct endpoint *endpoint;
uint16_t size, id;
int ready;
if (skipstone_link_recv(link, service->buf, &size, &id) < 0) {
if ((ready = skipstone_link_recv(link, service->buf, &size, &id, timeout)) < 0) {
goto error_io;
}
if ((endpoint = skipstone_map_get(service->endpoints, id)) != NULL) {
if (ready && (endpoint = skipstone_map_get(service->endpoints, id)) != NULL) {
if (endpoint->handler(service, service->buf, size, id, endpoint->context) < 0) {
goto error_io;
}
@ -324,17 +325,3 @@ int skipstone_message_service_next_event(skipstone_message_service *service,
error_io:
return -1;
}
int skipstone_message_service_run(skipstone_message_service *service,
skipstone_link *link) {
while (1) {
if (skipstone_message_service_next_event(service, link) < 0) {
goto error_service_next_event;
}
}
return 0;
error_service_next_event:
return -1;
}