[Groonga-commit] groonga/groonga [master] stop accepting when no file descriptor is remained. #802

Back to archive index

null+****@clear***** null+****@clear*****
2010年 12月 29日 (水) 17:11:21 JST


Kouhei Sutou	2010-12-29 08:11:21 +0000 (Wed, 29 Dec 2010)

  New Revision: 66af4bdae6f36217ba183cf7e3ceaeb1ca335df4

  Log:
    stop accepting when no file descriptor is remained. #802

  Modified files:
    lib/com.c
    lib/com.h
    src/groonga.c

  Modified: lib/com.c (+50 -4)
===================================================================
--- lib/com.c    2010-12-29 03:38:15 +0000 (632d86c)
+++ lib/com.c    2010-12-29 08:11:21 +0000 (c81a4b9)
@@ -438,6 +438,44 @@ grn_com_event_del(grn_ctx *ctx, grn_com_event *ev, grn_sock fd)
   }
 }
 
+#define LISTEN_BACKLOG 0x1000
+
+grn_rc
+grn_com_event_start_accept(grn_ctx *ctx, grn_com_event *ev)
+{
+  grn_com *com = ev->acceptor;
+
+  if (com->accepting) {return ctx->rc;}
+
+  GRN_API_ENTER;
+  if (!grn_com_event_mod(ctx, ev, com->fd, GRN_COM_POLLIN, NULL)) {
+    if (listen(com->fd, LISTEN_BACKLOG) == 0) {
+      com->accepting = GRN_TRUE;
+    } else {
+      SERR("listen - start accept");
+    }
+  }
+  GRN_API_RETURN(ctx->rc);
+}
+
+grn_rc
+grn_com_event_stop_accept(grn_ctx *ctx, grn_com_event *ev)
+{
+  grn_com *com = ev->acceptor;
+
+  if (!com->accepting) {return ctx->rc;}
+
+  GRN_API_ENTER;
+  if (!grn_com_event_mod(ctx, ev, com->fd, 0, NULL)) {
+    if (listen(com->fd, 0) == 0) {
+      com->accepting = GRN_FALSE;
+    } else {
+      SERR("listen - disable accept");
+    }
+  }
+  GRN_API_RETURN(ctx->rc);
+}
+
 static void
 grn_com_receiver(grn_ctx *ctx, grn_com *com)
 {
@@ -447,7 +485,11 @@ grn_com_receiver(grn_ctx *ctx, grn_com *com)
     grn_com *ncs;
     grn_sock fd = accept(com->fd, NULL, NULL);
     if (fd == -1) {
-      SERR("accept");
+      if (errno == EMFILE) {
+        grn_com_event_stop_accept(ctx, ev);
+      } else {
+        SERR("accept");
+      }
       return;
     }
     if (grn_com_event_add(ctx, ev, fd, GRN_COM_POLLIN, (grn_com **)&ncs)) {
@@ -471,6 +513,7 @@ grn_com_receiver(grn_ctx *ctx, grn_com *com)
       }
       msg->edge_id.sid = com->sid;
     }
+    msg->acceptor = ev->acceptor;
     ev->msg_handler(ctx, (grn_obj *)msg);
   }
 }
@@ -883,14 +926,16 @@ grn_com_close(grn_ctx *ctx, grn_com *com)
 {
   grn_sock fd = com->fd;
   grn_com_event *ev = com->ev;
-  if (ev) { grn_com_event_del(ctx, ev, fd); }
+  if (ev) {
+    grn_com *acceptor = ev->acceptor;
+    grn_com_event_del(ctx, ev, fd);
+    if (acceptor) { grn_com_event_start_accept(ctx, ev); }
+  }
   if (!com->closed) { grn_com_close_(ctx, com); }
   if (!ev) { GRN_FREE(com); }
   return GRN_SUCCESS;
 }
 
-#define LISTEN_BACKLOG 0x1000
-
 grn_rc
 grn_com_sopen(grn_ctx *ctx, grn_com_event *ev,
               const char *listen_address, int port, grn_msg_handler *func,
@@ -967,6 +1012,7 @@ grn_com_sopen(grn_ctx *ctx, grn_com_event *ev,
     if (!(cs = GRN_MALLOC(sizeof(grn_com)))) { goto exit; }
     cs->fd = lfd;
   }
+  cs->accepting = GRN_TRUE;
 exit :
   if (!cs) { grn_sock_close(lfd); }
   if (listen_address_info) { freeaddrinfo(listen_address_info); }

  Modified: lib/com.h (+4 -0)
===================================================================
--- lib/com.h    2010-12-29 03:38:15 +0000 (d2e096a)
+++ lib/com.h    2010-12-29 08:11:21 +0000 (0eb85dc)
@@ -127,6 +127,7 @@ struct _grn_com {
   grn_com_queue new;
   grn_com_event *ev;
   void *opaque;
+  grn_bool accepting;
 };
 
 struct _grn_com_event {
@@ -160,6 +161,8 @@ grn_rc grn_com_init(void);
 void grn_com_fin(void);
 GRN_API grn_rc grn_com_event_init(grn_ctx *ctx, grn_com_event *ev, int max_nevents, int data_size);
 GRN_API grn_rc grn_com_event_fin(grn_ctx *ctx, grn_com_event *ev);
+grn_rc grn_com_event_start_accept(grn_ctx *ctx, grn_com_event *ev);
+grn_rc grn_com_event_stop_accept(grn_ctx *ctx, grn_com_event *ev);
 grn_rc grn_com_event_add(grn_ctx *ctx, grn_com_event *ev, grn_sock fd, int events, grn_com **com);
 grn_rc grn_com_event_mod(grn_ctx *ctx, grn_com_event *ev, grn_sock fd, int events, grn_com **com);
 GRN_API grn_rc grn_com_event_del(grn_ctx *ctx, grn_com_event *ev, grn_sock fd);
@@ -214,6 +217,7 @@ struct _grn_msg {
   grn_com_queue *old;
   grn_com_header header;
   grn_com_addr edge_id;
+  grn_com *acceptor;
 };
 
 GRN_API grn_rc grn_msg_send(grn_ctx *ctx, grn_obj *msg, int flags);

  Modified: src/groonga.c (+1 -0)
===================================================================
--- src/groonga.c    2010-12-29 03:38:15 +0000 (82edfe8)
+++ src/groonga.c    2010-12-29 08:11:21 +0000 (b59e214)
@@ -888,6 +888,7 @@ exit :
   grn_msg_close(ctx, (grn_obj *)msg);
   /* if not keep alive connection */
   grn_sock_close(fd);
+  grn_com_event_start_accept(ctx, msg->acceptor->ev);
 }
 
 enum {




Groonga-commit メーリングリストの案内
Back to archive index