diff options
| author | Igor Sysoev <igor@sysoev.ru> | 2009-04-29 15:29:12 +0000 |
|---|---|---|
| committer | Igor Sysoev <igor@sysoev.ru> | 2009-04-29 15:29:12 +0000 |
| commit | a1580f58dd51109594e882f08a0c470ebc14ed37 (patch) | |
| tree | 213a22baf4ac1fbc47a3dac4757f439aba6f8306 /src | |
| parent | b70b1f7c647a78de6d7761fa2fe30cacd1504ac3 (diff) | |
| download | nginx-a1580f58dd51109594e882f08a0c470ebc14ed37.tar.gz nginx-a1580f58dd51109594e882f08a0c470ebc14ed37.tar.bz2 | |
ngx_select_repair_fd_sets()
Diffstat (limited to 'src')
| -rw-r--r-- | src/event/modules/ngx_select_module.c | 96 |
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) { |
