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 {