aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/event/modules/ngx_select_module.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/src/event/modules/ngx_select_module.c b/src/event/modules/ngx_select_module.c
index aa7c42ab7..11b5716e9 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);
@@ -343,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;
}
@@ -365,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;
}
@@ -425,6 +436,91 @@ ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
}
+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)
{