Use select() for arbitrary read timeouts
This commit is contained in:
parent
680e42c8ef
commit
f76c017783
10 changed files with 74 additions and 50 deletions
|
@ -27,7 +27,7 @@ int main(int argc, char **argv) {
|
||||||
goto error_link_open;
|
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",
|
printf("Received message %hu bytes for endpoint %hu\n",
|
||||||
len, endpoint);
|
len, endpoint);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ int main(int argc, char **argv) {
|
||||||
goto error_link_open;
|
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",
|
printf("Received message %hu bytes for endpoint %hu\n",
|
||||||
len, endpoint);
|
len, endpoint);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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, 17, answer_phone_version_message, NULL);
|
||||||
skipstone_message_service_register(service, 32, answer_music_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);
|
skipstone_link_close(link);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
error_io:
|
||||||
error_message_service_new:
|
error_message_service_new:
|
||||||
skipstone_link_close(link);
|
skipstone_link_close(link);
|
||||||
|
|
||||||
|
|
|
@ -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, 17, answer_phone_version_message, NULL);
|
||||||
skipstone_message_service_register(service, 32, answer_music_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);
|
skipstone_link_close(link);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
error_io:
|
||||||
error_message_service_new:
|
error_message_service_new:
|
||||||
skipstone_link_close(link);
|
skipstone_link_close(link);
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define _SKIPSTONE_LINK_H
|
#define _SKIPSTONE_LINK_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
typedef struct _skipstone_link skipstone_link;
|
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_close(skipstone_link *link);
|
||||||
|
|
||||||
int skipstone_link_send(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,
|
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 */
|
#endif /* _SKIPSTONE_LINK_H */
|
||||||
|
|
|
@ -73,9 +73,6 @@ int skipstone_message_service_queue(skipstone_message_service *service,
|
||||||
skipstone_message *message, uint16_t id);
|
skipstone_message *message, uint16_t id);
|
||||||
|
|
||||||
int skipstone_message_service_next_event(skipstone_message_service *service,
|
int skipstone_message_service_next_event(skipstone_message_service *service,
|
||||||
skipstone_link *link);
|
skipstone_link *link, struct timeval *timeout);
|
||||||
|
|
||||||
int skipstone_message_service_run(skipstone_message_service *service,
|
|
||||||
skipstone_link *link);
|
|
||||||
|
|
||||||
#endif /* _SKIPSTONE_MESSAGE_H */
|
#endif /* _SKIPSTONE_MESSAGE_H */
|
||||||
|
|
20
src/link.c
20
src/link.c
|
@ -6,6 +6,7 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/select.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#include <skipstone/link.h>
|
#include <skipstone/link.h>
|
||||||
|
@ -134,12 +135,27 @@ error_toobig:
|
||||||
return -1;
|
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;
|
skipstone_message_header header;
|
||||||
|
|
||||||
ssize_t len_read;
|
ssize_t len_read;
|
||||||
size_t len_wanted, offset = 0;
|
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) {
|
if (read(link->serial.fd, &header, sizeof(header)) < 0) {
|
||||||
goto error_io;
|
goto error_io;
|
||||||
}
|
}
|
||||||
|
@ -162,7 +178,7 @@ int skipstone_link_recv(skipstone_link *link, void *buf, uint16_t *size, uint16_
|
||||||
*size = be16toh(header.size);
|
*size = be16toh(header.size);
|
||||||
*id = be16toh(header.id);
|
*id = be16toh(header.id);
|
||||||
|
|
||||||
return 0;
|
return 1;
|
||||||
|
|
||||||
error_io:
|
error_io:
|
||||||
return -1;
|
return -1;
|
||||||
|
|
20
src/link.c-e
20
src/link.c-e
|
@ -6,6 +6,7 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/select.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#include <skipstone/link.h>
|
#include <skipstone/link.h>
|
||||||
|
@ -134,12 +135,27 @@ error_toobig:
|
||||||
return -1;
|
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;
|
skipstone_message_header header;
|
||||||
|
|
||||||
ssize_t len_read;
|
ssize_t len_read;
|
||||||
size_t len_wanted, offset = 0;
|
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) {
|
if (read(link->serial.fd, &header, sizeof(header)) < 0) {
|
||||||
goto error_io;
|
goto error_io;
|
||||||
}
|
}
|
||||||
|
@ -162,7 +178,7 @@ int skipstone_link_recv(skipstone_link *link, void *buf, uint16_t *size, uint16_
|
||||||
*size = be16toh(header.size);
|
*size = be16toh(header.size);
|
||||||
*id = be16toh(header.id);
|
*id = be16toh(header.id);
|
||||||
|
|
||||||
return 0;
|
return 1;
|
||||||
|
|
||||||
error_io:
|
error_io:
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -298,16 +298,17 @@ error_malloc_packed:
|
||||||
}
|
}
|
||||||
|
|
||||||
int skipstone_message_service_next_event(skipstone_message_service *service,
|
int skipstone_message_service_next_event(skipstone_message_service *service,
|
||||||
skipstone_link *link) {
|
skipstone_link *link, struct timeval *timeout) {
|
||||||
skipstone_message_header *message;
|
skipstone_message_header *message;
|
||||||
struct endpoint *endpoint;
|
struct endpoint *endpoint;
|
||||||
uint16_t size, id;
|
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;
|
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) {
|
if (endpoint->handler(service, service->buf, size, id, endpoint->context) < 0) {
|
||||||
goto error_io;
|
goto error_io;
|
||||||
}
|
}
|
||||||
|
@ -324,17 +325,3 @@ int skipstone_message_service_next_event(skipstone_message_service *service,
|
||||||
error_io:
|
error_io:
|
||||||
return -1;
|
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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -298,16 +298,17 @@ error_malloc_packed:
|
||||||
}
|
}
|
||||||
|
|
||||||
int skipstone_message_service_next_event(skipstone_message_service *service,
|
int skipstone_message_service_next_event(skipstone_message_service *service,
|
||||||
skipstone_link *link) {
|
skipstone_link *link, struct timeval *timeout) {
|
||||||
skipstone_message_header *message;
|
skipstone_message_header *message;
|
||||||
struct endpoint *endpoint;
|
struct endpoint *endpoint;
|
||||||
uint16_t size, id;
|
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;
|
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) {
|
if (endpoint->handler(service, service->buf, size, id, endpoint->context) < 0) {
|
||||||
goto error_io;
|
goto error_io;
|
||||||
}
|
}
|
||||||
|
@ -324,17 +325,3 @@ int skipstone_message_service_next_event(skipstone_message_service *service,
|
||||||
error_io:
|
error_io:
|
||||||
return -1;
|
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;
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue