From 45b59d87c07ca0038f98aea499435e502f0ba80b Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Mon, 12 Jul 2021 21:54:22 +0200 Subject: [PATCH] Use a loopback UDP socket instead of a pipe. The ESP32 doesn't provide pipe(), to ensure we can wake up select() we have to use a socket bound to localhost so we can send a dummy packet to ourself. --- src/event.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/src/event.c b/src/event.c index 6385465..b74b47c 100644 --- a/src/event.c +++ b/src/event.c @@ -192,7 +192,7 @@ static void signalio_handler(event_loop_t *loop, void *data, int flags) { (void)flags; unsigned char signum; - if(read(loop->pipefd[0], &signum, 1) != 1) { + if(recv(loop->pipefd[0], &signum, 1, MSG_DONTWAIT) != 1) { return; } @@ -208,14 +208,32 @@ static void signalio_handler(event_loop_t *loop, void *data, int flags) { } } +static struct sockaddr_in loopback = {0}; + static void pipe_init(event_loop_t *loop) { - int result = pipe(loop->pipefd); - assert(result == 0); + meshlink_handle_t *mesh = loop->data; + + loop->pipefd[0] = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + loop->pipefd[1] = loop->pipefd[0]; + + if(loop->pipefd[0] == -1) { + logger(mesh, MESHLINK_ERROR, "Could not create UDP socket"); + return; + } + + loopback.sin_family = AF_INET; + loopback.sin_port = 1024; + loopback.sin_addr.s_addr = htonl(0x7F000001); + + int result = bind(loop->pipefd[0], (struct sockaddr *)&loopback, sizeof(loopback)); + + if(result == -1) { + logger(mesh, MESHLINK_ERROR, "Could not bind UDP socket to localhost"); + } if(result == 0) { #ifdef O_NONBLOCK fcntl(loop->pipefd[0], F_SETFL, O_NONBLOCK); - fcntl(loop->pipefd[1], F_SETFL, O_NONBLOCK); #endif io_add(loop, &loop->signalio, signalio_handler, NULL, loop->pipefd[0], IO_READ); } @@ -225,13 +243,14 @@ static void pipe_exit(event_loop_t *loop) { io_del(loop, &loop->signalio); close(loop->pipefd[0]); - close(loop->pipefd[1]); loop->pipefd[0] = -1; loop->pipefd[1] = -1; } void signal_trigger(event_loop_t *loop, signal_t *sig) { + meshlink_handle_t *mesh = loop->data; + #ifdef HAVE_STDATOMIC_H if(atomic_flag_test_and_set(&sig->set)) { @@ -241,7 +260,7 @@ void signal_trigger(event_loop_t *loop, signal_t *sig) { #endif uint8_t signum = sig->signum; - write(loop->pipefd[1], &signum, 1); + sendto(loop->pipefd[1], &signum, 1, MSG_DONTWAIT, (struct sockaddr *)&loopback, sizeof(loopback)); return; } -- 2.39.5