# HG changeset patch # User Igor Sysoev # Date 1077052287 0 # Node ID bdd631bf1a1c7ebf984347c8fe41b6c3a029d7cf # Parent 5dacbb4daaf6084555b54276e64761bf855a072a nginx-0.0.2-2004-02-18-00:11:27 import diff --git a/auto/os/freebsd b/auto/os/freebsd --- a/auto/os/freebsd +++ b/auto/os/freebsd @@ -4,8 +4,8 @@ CORE_DEPS="$UNIX_DEPS $FREEBSD_DEPS" CORE_SRCS="$UNIX_SRCS $FREEBSD_SRCS" -# __FreeBSD_version is the best way to learn when -# some capability appeared or became safe to use +# __FreeBSD_version is the best way to determine whether +# some capability exists and is safe to use version=`grep "#define __FreeBSD_version" /usr/include/osreldate.h \ | sed -e 's/^.* \(.*\)$/\1/'` diff --git a/src/event/modules/ngx_aio_module.c b/src/event/modules/ngx_aio_module.c --- a/src/event/modules/ngx_aio_module.c +++ b/src/event/modules/ngx_aio_module.c @@ -13,7 +13,7 @@ static int ngx_aio_init(ngx_cycle_t *cyc static void ngx_aio_done(ngx_cycle_t *cycle); static int ngx_aio_add_event(ngx_event_t *ev, int event, u_int flags); static int ngx_aio_del_event(ngx_event_t *ev, int event, u_int flags); -static int ngx_aio_del_connection(ngx_connection_t *c); +static int ngx_aio_del_connection(ngx_connection_t *c, u_int flags); static int ngx_aio_process_events(ngx_log_t *log); @@ -96,7 +96,7 @@ static int ngx_aio_del_event(ngx_event_t } -static int ngx_aio_del_connection(ngx_connection_t *c) +static int ngx_aio_del_connection(ngx_connection_t *c, u_int flags) { int rc; diff --git a/src/event/modules/ngx_iocp_module.c b/src/event/modules/ngx_iocp_module.c --- a/src/event/modules/ngx_iocp_module.c +++ b/src/event/modules/ngx_iocp_module.c @@ -13,7 +13,7 @@ static int ngx_iocp_init(ngx_cycle_t *cycle); static void ngx_iocp_done(ngx_cycle_t *cycle); static int ngx_iocp_add_event(ngx_event_t *ev, int event, u_int key); -static int ngx_iocp_del_connection(ngx_connection_t *c); +static int ngx_iocp_del_connection(ngx_connection_t *c, u_int flags); static int ngx_iocp_process_events(ngx_log_t *log); static void *ngx_iocp_create_conf(ngx_cycle_t *cycle); static char *ngx_iocp_init_conf(ngx_cycle_t *cycle, void *conf); @@ -154,7 +154,7 @@ static int ngx_iocp_add_event(ngx_event_ } -static int ngx_iocp_del_connection(ngx_connection_t *c) +static int ngx_iocp_del_connection(ngx_connection_t *c, u_int flags) { if (CancelIo((HANDLE) c->fd) == 0) { ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, "CancelIo() failed"); diff --git a/src/event/modules/ngx_poll_module.c b/src/event/modules/ngx_poll_module.c --- a/src/event/modules/ngx_poll_module.c +++ b/src/event/modules/ngx_poll_module.c @@ -13,7 +13,7 @@ static int ngx_poll_init(ngx_cycle_t *cy static void ngx_poll_done(ngx_cycle_t *cycle); static int ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags); static int ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags); -static int ngx_poll_process_events(ngx_log_t *log); +int ngx_poll_process_events(ngx_log_t *log); static struct pollfd *event_list; @@ -245,7 +245,7 @@ static int ngx_poll_del_event(ngx_event_ } -static int ngx_poll_process_events(ngx_log_t *log) +int ngx_poll_process_events(ngx_log_t *log) { int ready; ngx_int_t i, j, nready, found; @@ -257,13 +257,19 @@ static int ngx_poll_process_events(ngx_l ngx_connection_t *c; struct timeval tv; - timer = ngx_event_find_timer(); - ngx_old_elapsed_msec = ngx_elapsed_msec; + if (ngx_event_flags & NGX_OVERFLOW_EVENT) { + timer = 0; + + } else { + timer = ngx_event_find_timer(); - if (timer == 0) { - timer = (ngx_msec_t) INFTIM; + if (timer == 0) { + timer = (ngx_msec_t) INFTIM; + } } + ngx_old_elapsed_msec = ngx_elapsed_msec; + #if (NGX_DEBUG0) for (i = 0; i < nevents; i++) { ngx_log_debug3(NGX_LOG_DEBUG_EVENT, log, 0, "poll: %d: fd:%d ev:%04X", @@ -309,6 +315,11 @@ static int ngx_poll_process_events(ngx_l } } + if (timer == 0 && ready == 0) { + /* the overflowed rt signals queue has been drained */ + return NGX_OK; + } + nready = 0; for (i = 0; i < nevents && ready; i++) { @@ -431,5 +442,5 @@ static int ngx_poll_process_events(ngx_l ngx_event_expire_timers((ngx_msec_t) delta); } - return NGX_OK; + return nready; } diff --git a/src/event/modules/ngx_rtsig_module.c b/src/event/modules/ngx_rtsig_module.c --- a/src/event/modules/ngx_rtsig_module.c +++ b/src/event/modules/ngx_rtsig_module.c @@ -15,15 +15,9 @@ #define SIGRTMIN 33 #define si_fd __spare__[0] -int sigwaitinfo(const sigset_t *set, siginfo_t *info); - int sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout); -int sigwaitinfo(const sigset_t *set, siginfo_t *info) -{ - return -1; -} int sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout) @@ -39,11 +33,14 @@ typedef struct { } ngx_rtsig_conf_t; +extern ngx_event_module_t ngx_poll_module_ctx; + static int ngx_rtsig_init(ngx_cycle_t *cycle); static void ngx_rtsig_done(ngx_cycle_t *cycle); static int ngx_rtsig_add_connection(ngx_connection_t *c); -static int ngx_rtsig_del_connection(ngx_connection_t *c); +static int ngx_rtsig_del_connection(ngx_connection_t *c, u_int flags); static int ngx_rtsig_process_events(ngx_log_t *log); +static int ngx_rtsig_process_overlow(ngx_log_t *log); static void *ngx_rtsig_create_conf(ngx_cycle_t *cycle); static char *ngx_rtsig_init_conf(ngx_cycle_t *cycle, void *conf); @@ -100,6 +97,10 @@ static int ngx_rtsig_init(ngx_cycle_t *c { ngx_rtsig_conf_t *rtscf; + if (ngx_poll_module_ctx.actions.init(cycle) == NGX_ERROR) { + return NGX_ERROR; + } + rtscf = ngx_event_get_conf(cycle->conf_ctx, ngx_rtsig_module); sigemptyset(&set); @@ -124,6 +125,7 @@ static int ngx_rtsig_init(ngx_cycle_t *c static void ngx_rtsig_done(ngx_cycle_t *cycle) { + ngx_poll_module_ctx.actions.done(cycle); } @@ -169,8 +171,16 @@ static int ngx_rtsig_add_connection(ngx_ } -static int ngx_rtsig_del_connection(ngx_connection_t *c) +static int ngx_rtsig_del_connection(ngx_connection_t *c, u_int flags) { + if (!(flags & NGX_CLOSE_EVENT)) { + if (fcntl(c->fd, F_SETFL, O_RDWR|O_NONBLOCK) == -1) { + ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, + "fcntl(O_RDWR|O_NONBLOCK) failed"); + return NGX_ERROR; + } + } + c->read->active = 0; c->write->active = 0; @@ -188,7 +198,7 @@ int ngx_rtsig_process_events(ngx_log_t * ngx_cycle_t **cycle; siginfo_t si; struct timeval tv; - struct timespec ts; + struct timespec ts, *tp; struct sigaction sa; ngx_connection_t *c; ngx_epoch_msec_t delta; @@ -200,15 +210,17 @@ int ngx_rtsig_process_events(ngx_log_t * if (timer) { ts.tv_sec = timer / 1000; ts.tv_nsec = (timer % 1000) * 1000000; + tp = &ts; + + } else { + tp = NULL; } ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0, "rtsig timer: %d", timer); - if (timer) { - signo = sigtimedwait(&set, &si, &ts); - } else { - signo = sigwaitinfo(&set, &si); - } + /* Linux sigwaitinfo() is sigtimedwait() with the NULL timeout pointer */ + + signo = sigtimedwait(&set, &si, tp); if (signo == -1) { err = ngx_errno; @@ -222,10 +234,9 @@ int ngx_rtsig_process_events(ngx_log_t * delta = ngx_elapsed_msec; ngx_elapsed_msec = tv.tv_sec * 1000 + tv.tv_usec / 1000 - ngx_start_msec; - if (signo == -1) { + if (err) { ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT, - log, err, - timer ? "sigtimedwait() failed" : "sigwaitinfo() failed"); + log, err, "sigtimedwait() failed"); return NGX_ERROR; } @@ -267,6 +278,8 @@ int ngx_rtsig_process_events(ngx_log_t * "signal queue overflowed: " "SIGIO, fd:%d, band:%X", si.si_fd, si.si_band); + /* TODO: flush all the used RT signals */ + ngx_memzero(&sa, sizeof(struct sigaction)); sa.sa_handler = SIG_DFL; sigemptyset(&sa.sa_mask); @@ -275,11 +288,17 @@ int ngx_rtsig_process_events(ngx_log_t * "sigaction(%d, SIG_DFL) failed", rtscf->signo); } + ngx_event_actions = ngx_poll_module_ctx.actions; + ngx_event_actions.process = ngx_rtsig_process_overflow; + ngx_event_flags = NGX_OVERFLOW_EVENT + |NGX_USE_LEVEL_EVENT|NGX_USE_ONESHOT_EVENT; + + /* STUB: add events. WHAT to do with fcntl()s ? */ + + } else { ngx_log_error(NGX_LOG_ALERT, log, 0, - timer ? "sigtimedwait() returned unexpected signal: %d": - "sigwaitinfo() returned unexpected signal: %d", - signo); + "sigtimedwait() returned unexpected signal: %d", signo); return NGX_ERROR; } @@ -291,6 +310,17 @@ int ngx_rtsig_process_events(ngx_log_t * } +static int ngx_rtsig_process_overlow(ngx_log_t *log) +{ + if (ngx_poll_module_ctx.actions.process(log) == NGX_OK) { + ngx_event_actions = ngx_rtsig_module_ctx.actions; + ngx_event_flags = NGX_USE_SIGIO_EVENT; + } + + return NGX_OK; +} + + static void *ngx_rtsig_create_conf(ngx_cycle_t *cycle) { ngx_rtsig_conf_t *rtscf; diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h @@ -163,7 +163,7 @@ typedef struct { int (*disable)(ngx_event_t *ev, int event, u_int flags); int (*add_conn)(ngx_connection_t *c); - int (*del_conn)(ngx_connection_t *c); + int (*del_conn)(ngx_connection_t *c, u_int flags); int (*process)(ngx_log_t *log); int (*init)(ngx_cycle_t *cycle); @@ -216,16 +216,21 @@ extern ngx_event_actions_t ngx_event_a #define NGX_USE_SIGIO_EVENT 0x00000040 /* + * The alternative event method after the rt signals queue overflow. + */ +#define NGX_OVERFLOW_EVENT 0x00000080 + +/* * No need to add or delete the event filters - overlapped, aio_read, * aioread, io_submit. */ -#define NGX_USE_AIO_EVENT 0x00000080 +#define NGX_USE_AIO_EVENT 0x00000100 /* * Need to add socket or handle only once - i/o completion port. * It also requires HAVE_AIO and NGX_USE_AIO_EVENT to be set. */ -#define NGX_USE_IOCP_EVENT 0x00000100 +#define NGX_USE_IOCP_EVENT 0x00000200 diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c --- a/src/http/modules/proxy/ngx_http_proxy_handler.c +++ b/src/http/modules/proxy/ngx_http_proxy_handler.c @@ -532,7 +532,7 @@ void ngx_http_proxy_close_connection(ngx /* TODO: move connection to the connection pool */ if (ngx_del_conn) { - ngx_del_conn(c); + ngx_del_conn(c, NGX_CLOSE_EVENT); } else { if (c->read->active) { diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -1538,7 +1538,7 @@ void ngx_http_close_connection(ngx_conne } if (ngx_del_conn) { - ngx_del_conn(c); + ngx_del_conn(c, NGX_CLOSE_EVENT); } else { if (c->read->active || c->read->disabled) {