From d9ddd4fd3d8bde2dbca569f593747dc3000475f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BChler?= Date: Sun, 4 Jan 2009 23:14:08 +0100 Subject: [PATCH] Remove out-of-fd-handling. --- include/lighttpd/chunk.h | 4 ++-- include/lighttpd/network.h | 3 +-- include/lighttpd/server.h | 4 +++- include/lighttpd/typedefs.h | 3 +-- src/actions.c | 4 ---- src/chunk.c | 8 +++++--- src/connection.c | 10 ---------- src/modules/mod_fastcgi.c | 16 +++++----------- src/network_sendfile.c | 2 -- src/network_write.c | 2 -- src/server.c | 7 ++++++- src/virtualrequest.c | 5 ----- 12 files changed, 23 insertions(+), 45 deletions(-) diff --git a/include/lighttpd/chunk.h b/include/lighttpd/chunk.h index c0b3c18..b57897f 100644 --- a/include/lighttpd/chunk.h +++ b/include/lighttpd/chunk.h @@ -59,7 +59,7 @@ struct chunkiter { ******************/ /* open the file cf->name if it is not already opened for reading - * may return HANDLER_GO_ON, HANDLER_ERROR, HANDLER_WAIT_FOR_FD + * may return HANDLER_GO_ON, HANDLER_ERROR */ LI_API handler_t chunkfile_open(struct vrequest *vr, chunkfile *cf); @@ -75,7 +75,7 @@ INLINE goffset chunkiter_length(chunkiter iter); * but needs to do io in case of FILE_CHUNK; it tries mmap and * falls back to read(...) * the data is _not_ marked as "done" - * may return HANDLER_GO_ON, HANDLER_ERROR, HANDLER_WAIT_FOR_FD + * may return HANDLER_GO_ON, HANDLER_ERROR */ LI_API handler_t chunkiter_read(struct vrequest *vr, chunkiter iter, off_t start, off_t length, char **data_start, off_t *data_len); diff --git a/include/lighttpd/network.h b/include/lighttpd/network.h index 024fed5..29c8344 100644 --- a/include/lighttpd/network.h +++ b/include/lighttpd/network.h @@ -15,8 +15,7 @@ typedef enum { NETWORK_STATUS_CONNECTION_CLOSE, NETWORK_STATUS_WAIT_FOR_EVENT, /**< read/write returned -1 with errno=EAGAIN/EWOULDBLOCK; no real IO was done internal: some io may be done */ - NETWORK_STATUS_WAIT_FOR_AIO_EVENT, /**< nothing done yet, read/write will be done somewhere else */ - NETWORK_STATUS_WAIT_FOR_FD, /**< need a fd to open a file */ + NETWORK_STATUS_WAIT_FOR_AIO_EVENT /**< nothing done yet, read/write will be done somewhere else */ } network_status_t; /** repeats write after EINTR */ diff --git a/include/lighttpd/server.h b/include/lighttpd/server.h index 458eb04..d3d818c 100644 --- a/include/lighttpd/server.h +++ b/include/lighttpd/server.h @@ -90,6 +90,8 @@ LI_API void server_stop(server *srv); /* exit asap with cleanup */ LI_API void server_exit(server *srv); -GString *server_current_timestamp(); +LI_API GString *server_current_timestamp(); + +LI_API void server_out_of_fds(server *srv); #endif diff --git a/include/lighttpd/typedefs.h b/include/lighttpd/typedefs.h index 8984cce..2862370 100644 --- a/include/lighttpd/typedefs.h +++ b/include/lighttpd/typedefs.h @@ -10,8 +10,7 @@ typedef enum { HANDLER_GO_ON, HANDLER_COMEBACK, HANDLER_WAIT_FOR_EVENT, - HANDLER_ERROR, - HANDLER_WAIT_FOR_FD + HANDLER_ERROR } handler_t; /* structs from headers, in alphabetic order */ diff --git a/src/actions.c b/src/actions.c index 8397bc1..98def87 100644 --- a/src/actions.c +++ b/src/actions.c @@ -219,7 +219,6 @@ handler_t action_execute(vrequest *vr) { action_stack_reset(vr, as); case HANDLER_COMEBACK: case HANDLER_WAIT_FOR_EVENT: - case HANDLER_WAIT_FOR_FD: return res; } continue; @@ -254,7 +253,6 @@ handler_t action_execute(vrequest *vr) { action_stack_reset(vr, as); case HANDLER_COMEBACK: case HANDLER_WAIT_FOR_EVENT: - case HANDLER_WAIT_FOR_FD: return res; } break; @@ -275,7 +273,6 @@ handler_t action_execute(vrequest *vr) { action_stack_reset(vr, as); case HANDLER_COMEBACK: case HANDLER_WAIT_FOR_EVENT: - case HANDLER_WAIT_FOR_FD: return res; } break; @@ -297,7 +294,6 @@ handler_t action_execute(vrequest *vr) { action_stack_reset(vr, as); case HANDLER_COMEBACK: case HANDLER_WAIT_FOR_EVENT: - case HANDLER_WAIT_FOR_FD: return res; } break; diff --git a/src/chunk.c b/src/chunk.c index 6905423..731778f 100644 --- a/src/chunk.c +++ b/src/chunk.c @@ -41,7 +41,7 @@ static void chunkfile_release(chunkfile *cf) { } /* open the file cf->name if it is not already opened for reading - * may return HANDLER_GO_ON, HANDLER_ERROR, HANDLER_WAIT_FOR_FD + * may return HANDLER_GO_ON, HANDLER_ERROR */ handler_t chunkfile_open(vrequest *vr, chunkfile *cf) { if (!cf) return HANDLER_ERROR; @@ -51,7 +51,9 @@ handler_t chunkfile_open(vrequest *vr, chunkfile *cf) { return HANDLER_ERROR; } if (-1 == (cf->fd = open(cf->name->str, O_RDONLY))) { - if (EMFILE == errno) return HANDLER_WAIT_FOR_FD; + if (EMFILE == errno) { + server_out_of_fds(vr->con->srv); + } VR_ERROR(vr, "Couldn't open file '%s': %s", GSTR_SAFE_STR(cf->name), g_strerror(errno)); return HANDLER_ERROR; } @@ -81,7 +83,7 @@ handler_t chunkfile_open(vrequest *vr, chunkfile *cf) { * but needs to do io in case of FILE_CHUNK; it tries mmap and * falls back to read(...) * the data is _not_ marked as "done" - * may return HANDLER_GO_ON, HANDLER_ERROR, HANDLER_WAIT_FOR_FD + * may return HANDLER_GO_ON, HANDLER_ERROR */ handler_t chunkiter_read(vrequest *vr, chunkiter iter, off_t start, off_t length, char **data_start, off_t *data_len) { chunk *c = chunkiter_chunk(iter); diff --git a/src/connection.c b/src/connection.c index aec6ea3..8dfc085 100644 --- a/src/connection.c +++ b/src/connection.c @@ -156,7 +156,6 @@ static gboolean connection_handle_read(connection *con) { return TRUE; case HANDLER_ERROR: case HANDLER_COMEBACK: /* unexpected */ - case HANDLER_WAIT_FOR_FD: /* unexpected */ /* unparsable header */ connection_error(con); return FALSE; @@ -211,10 +210,6 @@ static void connection_cb(struct ev_loop *loop, ev_io *w, int revents) { /* TODO: aio */ ev_io_rem_events(loop, w, EV_READ); break; - case NETWORK_STATUS_WAIT_FOR_FD: - /* TODO: wait for fd */ - ev_io_rem_events(loop, w, EV_READ); - break; } } } @@ -239,11 +234,6 @@ static void connection_cb(struct ev_loop *loop, ev_io *w, int revents) { _ERROR(con->srv, con->mainvr, "%s", "TODO: wait for aio"); /* TODO: aio */ break; - case NETWORK_STATUS_WAIT_FOR_FD: - ev_io_rem_events(loop, w, EV_WRITE); - _ERROR(con->srv, con->mainvr, "%s", "TODO: wait for fd"); - /* TODO: wait for fd */ - break; } } else { _DEBUG(con->srv, con->mainvr, "%s", "write event for empty queue"); diff --git a/src/modules/mod_fastcgi.c b/src/modules/mod_fastcgi.c index 9ce7efd..88b2577 100644 --- a/src/modules/mod_fastcgi.c +++ b/src/modules/mod_fastcgi.c @@ -461,10 +461,6 @@ static void fastcgi_fd_cb(struct ev_loop *loop, ev_io *w, int revents) { /* TODO: aio */ ev_io_rem_events(loop, w, EV_READ); break; - case NETWORK_STATUS_WAIT_FOR_FD: - /* TODO: wait for fd */ - ev_io_rem_events(loop, w, EV_READ); - break; } } } @@ -490,10 +486,6 @@ static void fastcgi_fd_cb(struct ev_loop *loop, ev_io *w, int revents) { ev_io_rem_events(loop, w, EV_WRITE); /* TODO: aio */ break; - case NETWORK_STATUS_WAIT_FOR_FD: - ev_io_rem_events(loop, w, EV_WRITE); - /* TODO: wait for fd */ - break; } } if (fcon->fcgi_out->length == 0) { @@ -533,10 +525,12 @@ static handler_t fastcgi_statemachine(vrequest *vr, fastcgi_connection *fcon) { /* fall through */ case FS_CONNECT: - fcon->fd = socket(fcon->ctx->socket.addr->plain.sa_family, SOCK_STREAM, 0); + do { + fcon->fd = socket(fcon->ctx->socket.addr->plain.sa_family, SOCK_STREAM, 0); + } while (-1 == fcon->fd && errno == EINTR); if (-1 == fcon->fd) { - if (errno == EMFILE || errno == EINTR) { - return HANDLER_WAIT_FOR_FD; + if (errno == EMFILE) { + server_out_of_fds(vr->con->srv); } VR_ERROR(vr, "Couldn't open socket: %s", g_strerror(errno)); return HANDLER_ERROR; diff --git a/src/network_sendfile.c b/src/network_sendfile.c index 7828e20..a38a41e 100644 --- a/src/network_sendfile.c +++ b/src/network_sendfile.c @@ -170,8 +170,6 @@ static network_status_t network_backend_sendfile(vrequest *vr, int fd, chunkqueu switch (chunkfile_open(vr, c->file.file)) { case HANDLER_GO_ON: break; - case HANDLER_WAIT_FOR_FD: - return NETWORK_STATUS_WAIT_FOR_FD; default: return NETWORK_STATUS_FATAL_ERROR; } diff --git a/src/network_write.c b/src/network_write.c index 7a42003..aa3bded 100644 --- a/src/network_write.c +++ b/src/network_write.c @@ -17,8 +17,6 @@ network_status_t network_backend_write(vrequest *vr, int fd, chunkqueue *cq, gof switch (chunkiter_read(vr, ci, 0, blocksize, &block_data, &block_len)) { case HANDLER_GO_ON: break; - case HANDLER_WAIT_FOR_FD: - return did_write_something ? NETWORK_STATUS_SUCCESS : NETWORK_STATUS_WAIT_FOR_FD; case HANDLER_ERROR: default: return NETWORK_STATUS_FATAL_ERROR; diff --git a/src/server.c b/src/server.c index af9cac5..328dd5a 100644 --- a/src/server.c +++ b/src/server.c @@ -230,7 +230,8 @@ static void server_listen_cb(struct ev_loop *loop, ev_io *w, int revents) { break; case EMFILE: /* we are out of FDs */ - /* TODO: server_out_of_fds(srv, NULL); */ + server_out_of_fds(srv); + /* TODO: disable accept callbacks? */ break; default: ERROR(srv, "accept failed on fd=%d with error: %s", w->fd, g_strerror(errno)); @@ -355,3 +356,7 @@ GString *server_current_timestamp() { return ts_str; } + +void server_out_of_fds(server *srv) { + ERROR(srv, "%s", "Too many open files. Either raise your fd limit or use a lower connection limit."); +} diff --git a/src/virtualrequest.c b/src/virtualrequest.c index 0d16cbc..b2047d1 100644 --- a/src/virtualrequest.c +++ b/src/virtualrequest.c @@ -212,7 +212,6 @@ static gboolean vrequest_do_handle_actions(vrequest *vr) { case HANDLER_COMEBACK: vrequest_joblist_append(vr); /* come back later */ return FALSE; - case HANDLER_WAIT_FOR_FD: /* TODO: wait for fd */ case HANDLER_WAIT_FOR_EVENT: return FALSE; case HANDLER_ERROR: @@ -235,7 +234,6 @@ static gboolean vrequest_do_handle_read(vrequest *vr) { case HANDLER_COMEBACK: vrequest_joblist_append(vr); /* come back later */ return FALSE; - case HANDLER_WAIT_FOR_FD: /* TODO: wait for fd */ case HANDLER_WAIT_FOR_EVENT: return FALSE; case HANDLER_ERROR: @@ -260,7 +258,6 @@ static gboolean vrequest_do_handle_write(vrequest *vr) { case HANDLER_COMEBACK: vrequest_joblist_append(vr); /* come back later */ return FALSE; - case HANDLER_WAIT_FOR_FD: /* TODO: wait for fd */ case HANDLER_WAIT_FOR_EVENT: return FALSE; case HANDLER_ERROR: @@ -297,7 +294,6 @@ void vrequest_state_machine(vrequest *vr) { vrequest_joblist_append(vr); /* come back later */ done = TRUE; break; - case HANDLER_WAIT_FOR_FD: /* TODO: wait for fd */ case HANDLER_WAIT_FOR_EVENT: done = (vr->state == VRS_HANDLE_REQUEST_HEADERS); break; @@ -323,7 +319,6 @@ void vrequest_state_machine(vrequest *vr) { vrequest_joblist_append(vr); /* come back later */ done = TRUE; break; - case HANDLER_WAIT_FOR_FD: /* TODO: wait for fd */ case HANDLER_WAIT_FOR_EVENT: done = (vr->state == VRS_HANDLE_REQUEST_HEADERS); break;