From def0caf2817be7d9f8c177cfc60df87a35bd3dae Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 18 Jun 2021 15:22:10 +0200 Subject: [PATCH] pulse-server: handle out-of-files better When we don't have enough files to accept the connection, clear the _IN flag so that we don't try to accept if over and over again. When a client disconnects, set the flag again so that we try to accecpt new connections again. See #1305 --- src/modules/module-protocol-pulse/internal.h | 1 + .../module-protocol-pulse/pulse-server.c | 25 ++++++++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/modules/module-protocol-pulse/internal.h b/src/modules/module-protocol-pulse/internal.h index 7ae60870b..62fa2ad6e 100644 --- a/src/modules/module-protocol-pulse/internal.h +++ b/src/modules/module-protocol-pulse/internal.h @@ -198,6 +198,7 @@ struct server { struct spa_source *source; struct spa_list clients; uint32_t n_clients; + uint32_t wait_clients; unsigned int activated:1; }; diff --git a/src/modules/module-protocol-pulse/pulse-server.c b/src/modules/module-protocol-pulse/pulse-server.c index 02a01a642..46801dc50 100644 --- a/src/modules/module-protocol-pulse/pulse-server.c +++ b/src/modules/module-protocol-pulse/pulse-server.c @@ -5350,14 +5350,22 @@ static int client_free_stream(void *item, void *data) */ static bool client_detach(struct client *client) { - if (client->server == NULL) + struct impl *impl = client->impl; + struct server *server = client->server; + + if (server == NULL) return false; - pw_log_info(NAME" %p: client %p detaching", client->server, client); + pw_log_info(NAME" %p: client %p detaching", server, client); /* remove from the `server->clients` list */ spa_list_remove(&client->link); - client->server->n_clients--; + server->n_clients--; + if (server->wait_clients > 0 && --server->wait_clients == 0) { + int mask = server->source->mask; + SPA_FLAG_SET(mask, SPA_IO_IN); + pw_loop_update_io(impl->loop, server->source, mask); + } client->server = NULL; return true; @@ -5777,8 +5785,17 @@ on_connect(void *data, int fd, uint32_t mask) length = sizeof(name); client_fd = accept4(fd, (struct sockaddr *) &name, &length, SOCK_CLOEXEC); - if (client_fd < 0) + if (client_fd < 0) { + if (errno == EMFILE || errno == ENFILE) { + if (server->n_clients > 0) { + int mask = server->source->mask; + SPA_FLAG_CLEAR(mask, SPA_IO_IN); + pw_loop_update_io(impl->loop, server->source, mask); + server->wait_clients++; + } + } goto error; + } if (server->n_clients >= MAX_CLIENTS) { close(client_fd);