| |
| |
| int ngx_sigio_add_event(ngx_event_t *ev, int signal) |
| { |
| ngx_connection_t *c; |
| |
| c = (ngx_connection_t *) ev->data; |
| |
| if (fcntl(c->fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC) == -1) { |
| ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, |
| "fcntl(O_RDWR|O_NONBLOCK|O_ASYNC) failed"); |
| return NGX_ERROR; |
| } |
| |
| if (fcntl(c->fd, F_SETSIG, signal) == -1) { |
| ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, |
| "fcntl(F_SETSIG) failed"); |
| return NGX_ERROR; |
| } |
| |
| if (fcntl(c->fd, F_SETOWN, pid) == -1) { |
| ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, |
| "fcntl(F_SETOWN) failed"); |
| return NGX_ERROR; |
| } |
| |
| #if (HAVE_ONESIGFD) |
| if (fcntl(c->fd, F_SETAUXFL, O_ONESIGFD) == -1) { |
| ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, |
| "fcntl(F_SETAUXFL) failed"); |
| return NGX_ERROR; |
| } |
| #endif |
| |
| return NGX_OK; |
| } |
| |
| int ngx_sigio_process_events(ngx_log_t *log) |
| { |
| struct siginfo si; |
| |
| for ( ;; ) { |
| if (timer) { |
| sig = sigtimedwait(&sigio_set, &si, &ts); |
| |
| if (sig == -1) { |
| ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, |
| "sigtimedwait() failed"); |
| continue; |
| } |
| } |
| |
| } else { |
| sig = sigwaitinfo(&set, &si); |
| |
| if (sig == -1) { |
| ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, |
| "sigwaitinfo() failed"); |
| } |
| } |
| |
| if (sig == rtsig) { |
| c = &ngx_connections[si.si_fd]; |
| |
| if (si.si_band & (POLLERR|POLLHUP|POLLNVAL)) { |
| ev = ???; |
| |
| if (ev->active) { |
| ev->ready = 1; |
| if (ev->event_handler(ev) == NGX_ERROR) { |
| ev->close_handler(ev); |
| } |
| } |
| } |
| |
| if (si.si_band & (POLLIN)) { |
| ev = c->read; |
| |
| if (ev->active) { |
| ev->ready = 1; |
| if (ev->event_handler(ev) == NGX_ERROR) { |
| ev->close_handler(ev); |
| } |
| } |
| } |
| |
| if (si.si_band & (POLLOUT)) { |
| ev = c->write; |
| |
| if (ev->active) { |
| ev->ready = 1; |
| if (ev->event_handler(ev) == NGX_ERROR) { |
| ev->close_handler(ev); |
| } |
| } |
| } |
| |
| } else if (sig == SIGIO) { |
| ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, |
| "Signal queue overflowed: " |
| "SIGIO, fd:%d, band:%d", si.si_fd, si.si_band); |
| |
| /* flush queue: method #1 (dphttpd) */ |
| ts.tv_sec = 0; |
| ts.tv_nsec = 0; |
| while (sigtimedwait(&sigio_set, &si, &ts) > 0); |
| |
| /* flush queue: method #2 (dkftpbench) */ |
| signal(m_signum, SIG_IGN); |
| signal(m_signum, SIG_DFL); |
| |
| /* do poll */ |
| |
| } else { |
| } |
| } |
| } |