From e094640c7b3a8b20124a8dd399baf6e488b2a437 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 2 Nov 2020 14:51:07 +0100 Subject: [PATCH] handle EINTR and EAGAIN Just do the call again instead of failing or logging an error. Fixes #358 --- pipewire-jack/src/pipewire-jack.c | 16 +++++++++++----- pipewire-pulseaudio/src/context.c | 5 ++++- pipewire-pulseaudio/src/mainloop-glib.c | 4 +++- pipewire-pulseaudio/src/mainloop.c | 4 +++- src/examples/media-session/media-session.c | 2 ++ src/pipewire/data-loop.c | 4 ++-- src/pipewire/main-loop.c | 5 ++++- src/pipewire/thread-loop.c | 5 ++++- 8 files changed, 33 insertions(+), 12 deletions(-) diff --git a/pipewire-jack/src/pipewire-jack.c b/pipewire-jack/src/pipewire-jack.c index 54a4f96a7..f3bd50909 100644 --- a/pipewire-jack/src/pipewire-jack.c +++ b/pipewire-jack/src/pipewire-jack.c @@ -1078,11 +1078,17 @@ static inline uint32_t cycle_run(struct client *c) struct pw_node_activation *driver = c->rt.driver_activation; /* this is blocking if nothing ready */ - if (SPA_UNLIKELY(read(fd, &cmd, sizeof(cmd)) != sizeof(cmd))) { - pw_log_warn(NAME" %p: read failed %m", c); - if (errno == EWOULDBLOCK) - return 0; - } else if (SPA_UNLIKELY(cmd > 1)) + while (true) { + if (SPA_UNLIKELY(read(fd, &cmd, sizeof(cmd)) != sizeof(cmd))) { + if (errno == EAGAIN || errno == EINTR) + continue; + if (errno == EWOULDBLOCK) + return 0; + pw_log_warn(NAME" %p: read failed %m", c); + } + break; + } + if (SPA_UNLIKELY(cmd > 1)) pw_log_warn(NAME" %p: missed %"PRIu64" wakeups", c, cmd - 1); clock_gettime(CLOCK_MONOTONIC, &ts); diff --git a/pipewire-pulseaudio/src/context.c b/pipewire-pulseaudio/src/context.c index c70d46e98..c394820a8 100644 --- a/pipewire-pulseaudio/src/context.c +++ b/pipewire-pulseaudio/src/context.c @@ -1654,11 +1654,14 @@ pa_operation* pa_context_subscribe(pa_context *c, pa_subscription_mask_t m, pa_c static void io_event_cb(pa_mainloop_api*ea, pa_io_event* e, int fd, pa_io_event_flags_t events, void *userdata) { + int res; pa_context *c = userdata; if (events & PA_IO_EVENT_INPUT) { pw_log_debug("%p: iterate loop %p", c, c->loop); pw_loop_enter(c->loop); - pw_loop_iterate(c->loop, -1); + do { + res = pw_loop_iterate(c->loop, 0); + } while (res == -EINTR || res == -EAGAIN); pw_loop_leave(c->loop); } } diff --git a/pipewire-pulseaudio/src/mainloop-glib.c b/pipewire-pulseaudio/src/mainloop-glib.c index 7addd7d3d..bd8899561 100644 --- a/pipewire-pulseaudio/src/mainloop-glib.c +++ b/pipewire-pulseaudio/src/mainloop-glib.c @@ -53,7 +53,9 @@ static gboolean source_dispatch (GSource *source, GSourceFunc callback, gpointer int result; pw_loop_enter (s->loop); - result = pw_loop_iterate (s->loop, 0); + do { + result = pw_loop_iterate (s->loop, 0); + } while (result == -EINTR || result == -EAGAIN); pw_loop_leave (s->loop); if (result < 0) diff --git a/pipewire-pulseaudio/src/mainloop.c b/pipewire-pulseaudio/src/mainloop.c index ec1820d36..0f30c1bdc 100644 --- a/pipewire-pulseaudio/src/mainloop.c +++ b/pipewire-pulseaudio/src/mainloop.c @@ -352,7 +352,9 @@ int pa_mainloop_poll(pa_mainloop *m) if (do_iterate) { pw_loop_enter(m->loop); - res = pw_loop_iterate(m->loop, timeout); + do { + res = pw_loop_iterate(m->loop, timeout); + } while (res == -EINTR || res == -EAGAIN); pw_loop_leave(m->loop); } diff --git a/src/examples/media-session/media-session.c b/src/examples/media-session/media-session.c index f1df141ce..a6621ffcf 100644 --- a/src/examples/media-session/media-session.c +++ b/src/examples/media-session/media-session.c @@ -1345,6 +1345,8 @@ int sm_media_session_roundtrip(struct sm_media_session *sess) pw_loop_enter(loop); while (!done) { if ((res = pw_loop_iterate(loop, -1)) < 0) { + if (res == -EINTR || res == -EAGAIN) + continue; pw_log_warn(NAME" %p: iterate error %d (%s)", loop, res, spa_strerror(res)); break; diff --git a/src/pipewire/data-loop.c b/src/pipewire/data-loop.c index adbd8c1f3..3c694320c 100644 --- a/src/pipewire/data-loop.c +++ b/src/pipewire/data-loop.c @@ -43,7 +43,7 @@ int pw_data_loop_wait(struct pw_data_loop *this, int timeout) break; } if ((res = pw_loop_iterate(this->loop, timeout)) < 0) { - if (errno == EINTR) + if (res == -EINTR || res == -EAGAIN) continue; } break; @@ -77,7 +77,7 @@ static void *do_loop(void *user_data) while (this->running) { if ((res = pw_loop_iterate(this->loop, -1)) < 0) { - if (errno == EINTR) + if (res == -EINTR || res == -EAGAIN) continue; pw_log_error(NAME" %p: iterate error %d (%s)", this, res, spa_strerror(res)); diff --git a/src/pipewire/main-loop.c b/src/pipewire/main-loop.c index b46fb1f4d..e58e18318 100644 --- a/src/pipewire/main-loop.c +++ b/src/pipewire/main-loop.c @@ -153,9 +153,12 @@ int pw_main_loop_run(struct pw_main_loop *loop) loop->running = true; pw_loop_enter(loop->loop); while (loop->running) { - if ((res = pw_loop_iterate(loop->loop, -1)) < 0) + if ((res = pw_loop_iterate(loop->loop, -1)) < 0) { + if (res == -EINTR || res == -EAGAIN) + continue; pw_log_warn(NAME" %p: iterate error %d (%s)", loop, res, spa_strerror(res)); + } } pw_loop_leave(loop->loop); return res; diff --git a/src/pipewire/thread-loop.c b/src/pipewire/thread-loop.c index 5052bff56..1b974c011 100644 --- a/src/pipewire/thread-loop.c +++ b/src/pipewire/thread-loop.c @@ -238,9 +238,12 @@ static void *do_loop(void *user_data) pw_loop_enter(this->loop); while (this->running) { - if ((res = pw_loop_iterate(this->loop, -1)) < 0) + if ((res = pw_loop_iterate(this->loop, -1)) < 0) { + if (res == -EINTR || res == -EAGAIN) + continue; pw_log_warn(NAME" %p: iterate error %d (%s)", this, res, spa_strerror(res)); + } } pw_log_debug(NAME" %p: leave thread", this); pw_loop_leave(this->loop);