summaryrefslogtreecommitdiff
path: root/src/event/modules
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2009-05-01 18:53:04 +0000
committerJonathan Kolb <jon@b0g.us>2009-05-01 18:53:04 +0000
commit1a537756bb9d3018ea6ab099b22e9734cc8a879d (patch)
tree6d2fe235b46b0de3053db6c84739db4f34e674e7 /src/event/modules
parentb04081c3ce5d031367a0142d57e287e26ba2e415 (diff)
downloadnginx-1a537756bb9d3018ea6ab099b22e9734cc8a879d.tar.gz
Changes with nginx 0.7.54 01 May 2009v0.7.54
*) Feature: the ngx_http_image_filter_module. *) Feature: the "proxy_ignore_headers" and "fastcgi_ignore_headers" directives. *) Bugfix: a segmentation fault might occur in worker process, if an "open_file_cache_errors off" directive was used; the bug had appeared in 0.7.53. *) Bugfix: the "port_in_redirect off" directive did not work; the bug had appeared in 0.7.39. *) Bugfix: improve handling of "select" method errors. *) Bugfix: of "select() failed (10022: ...)" error in nginx/Windows. *) Bugfix: in error text descriptions in nginx/Windows; the bug had appeared in 0.7.53.
Diffstat (limited to 'src/event/modules')
-rw-r--r--src/event/modules/ngx_select_module.c139
1 files changed, 121 insertions, 18 deletions
diff --git a/src/event/modules/ngx_select_module.c b/src/event/modules/ngx_select_module.c
index a50088ba4..9be2c6ff3 100644
--- a/src/event/modules/ngx_select_module.c
+++ b/src/event/modules/ngx_select_module.c
@@ -18,6 +18,7 @@ static ngx_int_t ngx_select_del_event(ngx_event_t *ev, ngx_int_t event,
ngx_uint_t flags);
static ngx_int_t ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
ngx_uint_t flags);
+static void ngx_select_repair_fd_sets(ngx_cycle_t *cycle);
static char *ngx_select_init_conf(ngx_cycle_t *cycle, void *conf);
@@ -248,12 +249,12 @@ static ngx_int_t
ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
ngx_uint_t flags)
{
- int ready, nready;
- ngx_uint_t i, found;
- ngx_err_t err;
- ngx_event_t *ev, **queue;
- ngx_connection_t *c;
- struct timeval tv, *tp;
+ int ready, nready;
+ ngx_err_t err;
+ ngx_uint_t i, found;
+ ngx_event_t *ev, **queue;
+ struct timeval tv, *tp;
+ ngx_connection_t *c;
#if !(NGX_WIN32)
@@ -302,19 +303,23 @@ ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
work_read_fd_set = master_read_fd_set;
work_write_fd_set = master_write_fd_set;
-#if 1
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- /*
- * (void *) disables "dereferencing type-punned
- * pointer will break strict-aliasing rules
- */
- "select read fd_set: %08Xd",
- *(int *) (void *) &work_read_fd_set);
-#endif
-
#if (NGX_WIN32)
- ready = select(0, &work_read_fd_set, &work_write_fd_set, NULL, tp);
+ if (max_read || max_write) {
+ ready = select(0, &work_read_fd_set, &work_write_fd_set, NULL, tp);
+
+ } else {
+
+ /*
+ * Winsock select() requires that at least one descriptor set must be
+ * be non-null, and any non-null descriptor set must contain at least
+ * one handle to a socket. Otherwise select() returns WSAEINVAL.
+ */
+
+ ngx_msleep(timer);
+
+ ready = 0;
+ }
#else
@@ -339,6 +344,11 @@ ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
if (err) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, err, "select() failed");
+
+ if (err == WSAENOTSOCK) {
+ ngx_select_repair_fd_sets(cycle);
+ }
+
return NGX_ERROR;
}
@@ -361,6 +371,11 @@ ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
}
ngx_log_error(level, cycle->log, err, "select() failed");
+
+ if (err == EBADF) {
+ ngx_select_repair_fd_sets(cycle);
+ }
+
return NGX_ERROR;
}
@@ -414,13 +429,101 @@ ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
ngx_mutex_unlock(ngx_posted_events_mutex);
if (ready != nready) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "select ready != events");
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+ "select ready != events: %d:%d", ready, nready);
+
+ ngx_select_repair_fd_sets(cycle);
}
return NGX_OK;
}
+static void
+ngx_select_repair_fd_sets(ngx_cycle_t *cycle)
+{
+ int n;
+ socklen_t len;
+ ngx_err_t err;
+ ngx_socket_t s;
+
+#if (NGX_WIN32)
+ u_int i;
+
+ for (i = 0; i < master_read_fd_set.fd_count; i++) {
+
+ s = master_read_fd_set.fd_array[i];
+ len = sizeof(int);
+
+ if (getsockopt(s, SOL_SOCKET, SO_TYPE, (char *) &n, &len) == -1) {
+ err = ngx_socket_errno;
+
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
+ "invalid descriptor #%d in read fd_set", s);
+
+ FD_CLR(s, &master_read_fd_set);
+ }
+ }
+
+ for (i = 0; i < master_write_fd_set.fd_count; i++) {
+
+ s = master_write_fd_set.fd_array[i];
+ len = sizeof(int);
+
+ if (getsockopt(s, SOL_SOCKET, SO_TYPE, (char *) &n, &len) == -1) {
+ err = ngx_socket_errno;
+
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
+ "invalid descriptor #%d in write fd_set", s);
+
+ FD_CLR(s, &master_write_fd_set);
+ }
+ }
+
+#else
+
+ for (s = 0; s <= max_fd; s++) {
+
+ if (FD_ISSET(s, &master_read_fd_set) == 0) {
+ continue;
+ }
+
+ len = sizeof(int);
+
+ if (getsockopt(s, SOL_SOCKET, SO_TYPE, &n, &len) == -1) {
+ err = ngx_socket_errno;
+
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
+ "invalid descriptor #%d in read fd_set", s);
+
+ FD_CLR(s, &master_read_fd_set);
+ }
+ }
+
+ for (s = 0; s <= max_fd; s++) {
+
+ if (FD_ISSET(s, &master_write_fd_set) == 0) {
+ continue;
+ }
+
+ len = sizeof(int);
+
+ if (getsockopt(s, SOL_SOCKET, SO_TYPE, &n, &len) == -1) {
+ err = ngx_socket_errno;
+
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
+ "invalid descriptor #%d in write fd_set", s);
+
+ FD_CLR(s, &master_write_fd_set);
+ }
+ }
+
+ max_fd = -1;
+
+#endif
+}
+
+
static char *
ngx_select_init_conf(ngx_cycle_t *cycle, void *conf)
{