From bf97beee4bbea1b07eb6dafc2b9eb08d9d17a294 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Sun, 21 Feb 2021 22:11:52 +0100 Subject: [PATCH] Add warning messages when checking for bad fds after select() returns an error. --- src/event.c | 28 ++++++++++++++++++++++------ src/event.h | 3 ++- src/net.c | 2 +- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/event.c b/src/event.c index 82133eb4..f8ebe8b8 100644 --- a/src/event.c +++ b/src/event.c @@ -21,6 +21,8 @@ #include "dropin.h" #include "event.h" +#include "logger.h" +#include "meshlink.h" #include "net.h" #include "splay_tree.h" #include "utils.h" @@ -282,7 +284,7 @@ void idle_set(event_loop_t *loop, idle_cb_t cb, void *data) { loop->idle_data = data; } -static void check_bad_fds(event_loop_t *loop) { +static void check_bad_fds(event_loop_t *loop, meshlink_handle_t *mesh) { // Just call all registered callbacks and have them check their fds do { @@ -309,6 +311,11 @@ static void check_bad_fds(event_loop_t *loop) { // Rebuild the fdsets + fd_set old_readfds; + fd_set old_writefds; + memcpy(&old_readfds, &loop->readfds, sizeof(old_readfds)); + memcpy(&old_writefds, &loop->writefds, sizeof(old_writefds)); + memset(&loop->readfds, 0, sizeof(loop->readfds)); memset(&loop->writefds, 0, sizeof(loop->writefds)); @@ -322,12 +329,19 @@ static void check_bad_fds(event_loop_t *loop) { FD_SET(io->fd, &loop->writefds); io->cb(loop, io->data, IO_WRITE); } + } + + if(memcmp(&old_readfds, &loop->readfds, sizeof(old_readfds))) { + logger(mesh, MESHLINK_WARNING, "Incorrect readfds fixed"); + } + if(memcmp(&old_writefds, &loop->writefds, sizeof(old_writefds))) { + logger(mesh, MESHLINK_WARNING, "Incorrect writefds fixed"); } } -bool event_loop_run(event_loop_t *loop, pthread_mutex_t *mutex) { - assert(mutex); +bool event_loop_run(event_loop_t *loop, meshlink_handle_t *mesh) { + assert(mesh); fd_set readable; fd_set writable; @@ -368,7 +382,7 @@ bool event_loop_run(event_loop_t *loop, pthread_mutex_t *mutex) { } // release mesh mutex during select - pthread_mutex_unlock(mutex); + pthread_mutex_unlock(&mesh->mutex); #ifdef HAVE_PSELECT int n = pselect(fds, &readable, &writable, NULL, &ts, NULL); @@ -377,7 +391,7 @@ bool event_loop_run(event_loop_t *loop, pthread_mutex_t *mutex) { int n = select(fds, &readable, &writable, NULL, (struct timeval *)&tv); #endif - if(pthread_mutex_lock(mutex) != 0) { + if(pthread_mutex_lock(&mesh->mutex) != 0) { abort(); } @@ -390,10 +404,12 @@ bool event_loop_run(event_loop_t *loop, pthread_mutex_t *mutex) { errors++; if(errors > 10) { + logger(mesh, MESHLINK_ERROR, "Unrecoverable error from select(): %s", strerror(errno)); return false; } - check_bad_fds(loop); + logger(mesh, MESHLINK_WARNING, "Error from select(), checking for bad fds: %s", strerror(errno)); + check_bad_fds(loop, mesh); continue; } } diff --git a/src/event.h b/src/event.h index bec32045..6b53d919 100644 --- a/src/event.h +++ b/src/event.h @@ -28,6 +28,7 @@ #define IO_WRITE 2 typedef struct event_loop_t event_loop_t; +struct meshlink_handle; typedef void (*io_cb_t)(event_loop_t *loop, void *data, int flags); typedef void (*timeout_cb_t)(event_loop_t *loop, void *data); @@ -96,7 +97,7 @@ void idle_set(event_loop_t *loop, idle_cb_t cb, void *data); void event_loop_init(event_loop_t *loop); void event_loop_exit(event_loop_t *loop); -bool event_loop_run(event_loop_t *loop, pthread_mutex_t *mutex) __attribute__((__warn_unused_result__)); +bool event_loop_run(event_loop_t *loop, struct meshlink_handle *mesh) __attribute__((__warn_unused_result__)); void event_loop_flush_output(event_loop_t *loop); void event_loop_start(event_loop_t *loop); void event_loop_stop(event_loop_t *loop); diff --git a/src/net.c b/src/net.c index 22f8287f..99c29c94 100644 --- a/src/net.c +++ b/src/net.c @@ -735,7 +735,7 @@ void main_loop(meshlink_handle_t *mesh) { mesh->datafromapp.signum = 0; signal_add(&mesh->loop, &mesh->datafromapp, meshlink_send_from_queue, mesh, mesh->datafromapp.signum); - if(!event_loop_run(&mesh->loop, &mesh->mutex)) { + if(!event_loop_run(&mesh->loop, mesh)) { logger(mesh, MESHLINK_ERROR, "Error while waiting for input: %s", strerror(errno)); call_error_cb(mesh, MESHLINK_ENETWORK); } -- 2.39.2