daemon: stop calling accept() when accept returns EMFILE 85/44485/1
authorSuchang Woo <suchang.woo@samsung.com>
Wed, 22 Jul 2015 11:48:33 +0000 (20:48 +0900)
committerSuchang Woo <suchang.woo@samsung.com>
Wed, 22 Jul 2015 12:02:43 +0000 (21:02 +0900)
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 <suchang.woo@samsung.com>
daemon/daemon.c
daemon/socks.c

index 69c5325..3146a75 100644 (file)
@@ -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();
index 2156a7b..b8ec210 100644 (file)
@@ -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);