From 125b7092012b3f2cf520251a99fb843956b3fb2f Mon Sep 17 00:00:00 2001 From: Suchang Woo Date: Wed, 22 Jul 2015 20:48:33 +0900 Subject: [PATCH] daemon: stop calling accept() when accept returns EMFILE When the number of open files exceed the maximum number(usually, 1024), accept() returns EMFILE (Too many open files). and, it is continued until the number of open files go below the maximum value. So, stop calling accept() on EMFILE. and, resume it when a client is closed. Change-Id: Ie8f3bfce3506e4ab56e3e8d37bbd573ddfd4685c Signed-off-by: Suchang Woo --- daemon/daemon.c | 57 +++++++++++++++++++++++++++++++++++++-------------------- daemon/socks.c | 2 +- 2 files changed, 38 insertions(+), 21 deletions(-) diff --git a/daemon/daemon.c b/daemon/daemon.c index 69c5325..3146a75 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -122,26 +122,6 @@ static void remove_noti_cli(struct bxt_daemon *bxtd, struct bxt_client *cli) } } -static void free_client(struct bxt_client *cli) -{ - if (!cli) - return; - - remove_noti_cli(cli->bxtd, cli); - g_list_free(cli->notilist); - cli->notilist = NULL; - - if (cli->fd_id) - g_source_remove(cli->fd_id); - - if (cli->fd != -1) - close(cli->fd); - - free(cli->label); - free(cli); - bxt_dbg("free client %p", cli); -} - static void remove_notilist(struct bxt_noti *noti) { GList *l; @@ -787,6 +767,11 @@ static gboolean accept_cb(gint fd, GIOCondition cond, gpointer data) cfd = accept(fd, (struct sockaddr *)&sa, &addrlen); if (cfd == -1) { + if (errno == EMFILE) { + bxt_err("Too many open files, stop calling accept()"); + bxtd->sk_id = 0; + return G_SOURCE_REMOVE; + } bxt_err("Accept: %d", errno); return G_SOURCE_CONTINUE; } @@ -796,6 +781,38 @@ static gboolean accept_cb(gint fd, GIOCondition cond, gpointer data) return G_SOURCE_CONTINUE; } +static void resume_accept(struct bxt_daemon *bxtd) +{ + assert(bxtd); + + if (bxtd->sk_id == 0) { + bxt_err("Resume calling accept()"); + bxtd->sk_id = g_unix_fd_add(bxtd->sk, G_IO_IN, accept_cb, bxtd); + } +} + +static void free_client(struct bxt_client *cli) +{ + if (!cli) + return; + + resume_accept(cli->bxtd); + + remove_noti_cli(cli->bxtd, cli); + g_list_free(cli->notilist); + cli->notilist = NULL; + + if (cli->fd_id) + g_source_remove(cli->fd_id); + + if (cli->fd != -1) + close(cli->fd); + + free(cli->label); + free(cli); + bxt_dbg("free client %p", cli); +} + static void bxt_exit(struct bxt_daemon *bxtd) { buxton_cynara_exit(); diff --git a/daemon/socks.c b/daemon/socks.c index 2156a7b..b8ec210 100644 --- a/daemon/socks.c +++ b/daemon/socks.c @@ -73,7 +73,7 @@ static int sock_create(const char *path) chmod(sa.sun_path, 0666); - r = listen(fd, 128); + r = listen(fd, SOMAXCONN); if (r == -1) { bxt_err("Socket '%s': listen %d", path, errno); close(fd); -- 2.7.4