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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define _SKIPSTONE_LINK_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
typedef struct _skipstone_link skipstone_link;
|
||||
|
||||
|
@ -13,6 +14,6 @@ int skipstone_link_send(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);
|
||||
void *buf, uint16_t *size, uint16_t *id, struct timeval *timeout);
|
||||
|
||||
#endif /* _SKIPSTONE_LINK_H */
|
||||
|
|
|
@ -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 */
|
||||
|
|
20
src/link.c
20
src/link.c
|
@ -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;
|
||||
|
|
20
src/link.c-e
20
src/link.c-e
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue