# HG changeset patch # User Igor Sysoev # Date 1053445075 0 # Node ID 19cc647ecd915de2df48259a3e9d19a9c2872017 # Parent 637625a2acdbded14df00f33678779dd93998067 nginx-0.0.1-2003-05-20-19:37:55 import diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -6,13 +6,6 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include #include #include #include @@ -55,8 +48,12 @@ int main(int argc, char *const *argv) ngx_str_t conf_file; ngx_conf_t conf; - /* STUB */ - ngx_log.log_level = NGX_LOG_DEBUG; + ngx_max_sockets = -1; + + ngx_log.fd = STDERR_FILENO; + ngx_log.log_level = NGX_LOG_INFO; + + /* STUB */ ngx_log.log_level = NGX_LOG_DEBUG; if (ngx_os_init(&ngx_log) == NGX_ERROR) { return 1; diff --git a/src/core/ngx_array.c b/src/core/ngx_array.c --- a/src/core/ngx_array.c +++ b/src/core/ngx_array.c @@ -29,7 +29,7 @@ void ngx_destroy_array(ngx_array_t *a) p = a->pool; - if (a->elts + a->size * a->nalloc == p->last) { + if ((char *) a->elts + a->size * a->nalloc == p->last) { p->last -= a->size * a->nalloc; } @@ -49,7 +49,7 @@ void *ngx_push_array(ngx_array_t *a) p = a->pool; /* array allocation is the last in the pool */ - if (a->elts + a->size * a->nelts == p->last + if ((char *) a->elts + a->size * a->nelts == p->last && (unsigned) (p->end - p->last) >= a->size) { p->last += a->size; @@ -65,7 +65,7 @@ void *ngx_push_array(ngx_array_t *a) } } - elt = a->elts + a->size * a->nelts; + elt = (char *) a->elts + a->size * a->nelts; a->nelts++; return elt; diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c --- a/src/core/ngx_conf_file.c +++ b/src/core/ngx_conf_file.c @@ -435,6 +435,10 @@ char *ngx_conf_set_flag_slot(ngx_conf_t int flag; ngx_str_t *value; + if (*(int *) (conf + cmd->offset) != NGX_CONF_UNSET) { + return "is duplicate"; + } + value = (ngx_str_t *) cf->args->elts; if (ngx_strcasecmp(value[1].data, "on") == 0) { @@ -458,6 +462,11 @@ char *ngx_conf_set_str_slot(ngx_conf_t * ngx_str_t *field, *value; field = (ngx_str_t *) (conf + cmd->offset); + + if (field->len > 0) { + return "is duplicate"; + } + value = (ngx_str_t *) cf->args->elts; field->len = value[1].len; @@ -472,6 +481,10 @@ char *ngx_conf_set_num_slot(ngx_conf_t * int num, len; ngx_str_t *value; + if (*(int *) (conf + cmd->offset) != NGX_CONF_UNSET) { + return "is duplicate"; + } + value = (ngx_str_t *) cf->args->elts; len = value[1].len; @@ -493,6 +506,10 @@ char *ngx_conf_set_size_slot(ngx_conf_t char last; ngx_str_t *value; + if (*(int *) (conf + cmd->offset) != NGX_CONF_UNSET) { + return "is duplicate"; + } + value = (ngx_str_t *) cf->args->elts; len = value[1].len; @@ -535,6 +552,10 @@ char *ngx_conf_set_msec_slot(ngx_conf_t char last, *start; ngx_str_t *value; + if (*(int *) (conf + cmd->offset) != NGX_CONF_UNSET) { + return "is duplicate"; + } + value = (ngx_str_t *) cf->args->elts; start = value[1].data; len = 0; @@ -626,6 +647,10 @@ char *ngx_conf_set_sec_slot(ngx_conf_t * char last, *start; ngx_str_t *value; + if (*(int *) (conf + cmd->offset) != NGX_CONF_UNSET) { + return "is duplicate"; + } + value = (ngx_str_t *) cf->args->elts; start = value[1].data; len = 0; diff --git a/src/core/ngx_config.h b/src/core/ngx_config.h --- a/src/core/ngx_config.h +++ b/src/core/ngx_config.h @@ -104,7 +104,7 @@ #endif -#if (HAVE_DEVPOLL) +#if (HAVE_DEVPOLL) && !(TEST_DEVPOLL) #include #include /* Solaris, HP/UX */ #endif diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -1,15 +1,22 @@ #ifndef _NGX_CONNECTION_H_INCLUDED_ #define _NGX_CONNECTION_H_INCLUDED_ +#include + +#if 0 #include #include #include #include #include #include +#endif + #include +#if 0 typedef struct ngx_connection_s ngx_connection_t; +#endif #ifdef NGX_EVENT #include @@ -81,12 +88,14 @@ EV_VNODE should notify by some si #endif +#if 0 typedef struct { ssize_t (*recv)(ngx_connection_t *c, char *buf, size_t size); void *dummy_recv_chain; void *dummy_send; ngx_chain_t *(*send_chain)(ngx_connection_t *c, ngx_chain_t *in); } ngx_os_io_t; +#endif extern ngx_os_io_t ngx_io; diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h --- a/src/core/ngx_core.h +++ b/src/core/ngx_core.h @@ -6,6 +6,11 @@ #include #include #include +#include +#include + +typedef struct ngx_connection_s ngx_connection_t; +typedef struct ngx_event_s ngx_event_t; #include #include @@ -14,8 +19,8 @@ #include #include #include +#include #include -#include @@ -38,4 +43,8 @@ */ +/* STUB */ +extern ngx_log_t ngx_log; + + #endif /* _NGX_CORE_H_INCLUDED_ */ diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c --- a/src/core/ngx_file.c +++ b/src/core/ngx_file.c @@ -14,7 +14,7 @@ static int ngx_random; int ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path, ngx_pool_t *pool, int persistent) { - int i, num; + int num; ngx_err_t err; file->name.len = path->name.len + 1 + path->len + 10; @@ -33,8 +33,8 @@ int ngx_create_temp_file(ngx_file_t *fil num = ngx_next_temp_number(0); for ( ;; ) { - snprintf(file->name.data + path->name.len + 1 + path->len, 11, - "%010u", num); + ngx_snprintf(file->name.data + path->name.len + 1 + path->len, 11, + "%010u", num); ngx_create_hashed_filename(file, path); diff --git a/src/core/ngx_file.h b/src/core/ngx_file.h --- a/src/core/ngx_file.h +++ b/src/core/ngx_file.h @@ -2,7 +2,6 @@ #define _NGX_FILE_H_INCLUDED_ -#include #include #include #include diff --git a/src/core/ngx_log.c b/src/core/ngx_log.c --- a/src/core/ngx_log.c +++ b/src/core/ngx_log.c @@ -11,15 +11,12 @@ */ #include -#include -#include -#include -#include -#include +#include static const char *err_levels[] = { - "emerg", "alert", "crit", "error", "warn", "notice", "info", "debug" + "stderr", "emerg", "alert", "crit", "error", + "warn", "notice", "info", "debug" }; #if (HAVE_VARIADIC_MACROS) @@ -30,11 +27,11 @@ void ngx_log_error_core(int level, ngx_l const char *fmt, va_list args) #endif { - char errstr[MAX_ERROR_STR]; - ngx_tm_t tm; - size_t len; + char errstr[MAX_ERROR_STR]; + ngx_tm_t tm; + size_t len; #if (HAVE_VARIADIC_MACROS) - va_list args; + va_list args; #endif ngx_localtime(&tm); @@ -93,7 +90,7 @@ void ngx_log_error_core(int level, ngx_l #endif errstr[len++] = '\n'; - write(2, errstr, len); + write(log->fd, errstr, len); #if 0 errstr[len] = '\0'; @@ -102,6 +99,7 @@ void ngx_log_error_core(int level, ngx_l #endif } + #if !(HAVE_VARIADIC_MACROS) void ngx_log_error(int level, ngx_log_t *log, ngx_err_t err, @@ -116,6 +114,7 @@ void ngx_log_error(int level, ngx_log_t } } + void ngx_log_debug_core(ngx_log_t *log, const char *fmt, ...) { va_list args; @@ -125,6 +124,7 @@ void ngx_log_debug_core(ngx_log_t *log, va_end(args); } + void ngx_assert_core(ngx_log_t *log, const char *fmt, ...) { va_list args; @@ -135,3 +135,33 @@ void ngx_assert_core(ngx_log_t *log, con } #endif + + +void ngx_log_stderr(ngx_event_t *ev) +{ + char errstr[MAX_ERROR_STR]; + ssize_t n; + ngx_err_t err; + + for ( ;; ) { + n = read((ngx_fd_t) ev->data, errstr, sizeof(errstr - 1)); + + if (n == -1) { + err = ngx_errno; + if (err == NGX_EAGAIN) { + return; + } + + ngx_log_error(NGX_LOG_ALERT, &ngx_log, err, "read() failed"); + return; + } + + if (n == 0) { + ngx_log_error(NGX_LOG_ALERT, &ngx_log, 0, "stderr clolsed"); + return; + } + + errstr[n] = '\0'; + ngx_log_error(NGX_LOG_STDERR, &ngx_log, 0, "%s", errstr); + } +} diff --git a/src/core/ngx_log.h b/src/core/ngx_log.h --- a/src/core/ngx_log.h +++ b/src/core/ngx_log.h @@ -6,7 +6,8 @@ #include typedef enum { - NGX_LOG_EMERG = 0, + NGX_LOG_STDERR = 0, + NGX_LOG_EMERG, NGX_LOG_ALERT, NGX_LOG_CRIT, NGX_LOG_ERR, @@ -16,6 +17,7 @@ typedef enum { NGX_LOG_DEBUG } ngx_log_e; + /* "[%time] [%level] %pid#%tid: %message:(%errno)%errstr, while %action" " %peer and while processing %context" @@ -59,6 +61,7 @@ typedef enum { "... while reading client command for 'john_doe'" */ + typedef struct { int log_level; ngx_fd_t fd; @@ -100,6 +103,7 @@ typedef struct { void ngx_log_error_core(int level, ngx_log_t *log, ngx_err_t err, const char *fmt, ...); + #elif (HAVE_C99_VARIADIC_MACROS) #define HAVE_VARIADIC_MACROS 1 @@ -125,6 +129,7 @@ void ngx_log_error_core(int level, ngx_l void ngx_log_error_core(int level, ngx_log_t *log, ngx_err_t err, const char *fmt, ...); + #else /* NO VARIADIC MACROS */ #include diff --git a/src/core/ngx_modules.c b/src/core/ngx_modules.c --- a/src/core/ngx_modules.c +++ b/src/core/ngx_modules.c @@ -8,9 +8,15 @@ extern ngx_module_t ngx_events_module; extern ngx_module_t ngx_event_module; extern ngx_module_t ngx_select_module; +#if (HAVE_POLL) +extern ngx_module_t ngx_poll_module; +#endif #if (HAVE_KQUEUE) extern ngx_module_t ngx_kqueue_module; #endif +#if (HAVE_DEVPOLL) +extern ngx_module_t ngx_devpoll_module; +#endif extern ngx_module_t ngx_http_module; @@ -32,9 +38,15 @@ ngx_module_t *ngx_modules[] = { &ngx_event_module, &ngx_select_module, +#if (HAVE_POLL) + &ngx_poll_module, +#endif #if (HAVE_KQUEUE) &ngx_kqueue_module, #endif +#if (HAVE_DEVPOLL) + &ngx_devpoll_module, +#endif /* http */ diff --git a/src/os/unix/ngx_os_init.h b/src/core/ngx_os_init.h rename from src/os/unix/ngx_os_init.h rename to src/core/ngx_os_init.h --- a/src/os/unix/ngx_os_init.h +++ b/src/core/ngx_os_init.h @@ -3,14 +3,24 @@ #include -#include -#include +#include +#if 0 #include +#endif + + +typedef struct { + ssize_t (*recv)(ngx_connection_t *c, char *buf, size_t size); + void *dummy_recv_chain; + void *dummy_send; + ngx_chain_t *(*send_chain)(ngx_connection_t *c, ngx_chain_t *in); +} ngx_os_io_t; int ngx_os_init(ngx_log_t *log); extern ngx_os_io_t ngx_os_io; +extern int ngx_max_sockets; #endif /* _NGX_OS_INIT_H_INCLUDED_ */ diff --git a/src/event/modules/ngx_devpoll_module.c b/src/event/modules/ngx_devpoll_module.c --- a/src/event/modules/ngx_devpoll_module.c +++ b/src/event/modules/ngx_devpoll_module.c @@ -1,47 +1,122 @@ + /* - * Copyright (C) 2002 Igor Sysoev, http://sysoev.ru + * Copyright (C) 2002-2003 Igor Sysoev, http://sysoev.ru */ #include #include -#include -#include #include #include -#include -#include + + +#if (TEST_DEVPOLL) + +/* Solaris declarations */ -#if (USE_DEVPOLL) && !(HAVE_DEVPOLL) -#error "/dev/poll is not supported on this platform" +#define POLLREMOVE 0x0800 +#define DP_POLL 0xD001 + +struct dvpoll { + struct pollfd *dp_fds; + int dp_nfds; + int dp_timeout; +}; + #endif + +typedef struct { + int changes; + int events; +} ngx_devpoll_conf_t; + + +static int ngx_devpoll_init(ngx_log_t *log); +static void ngx_devpoll_done(ngx_log_t *log); +static int ngx_devpoll_add_event(ngx_event_t *ev, int event, u_int flags); +static int ngx_devpoll_del_event(ngx_event_t *ev, int event, u_int flags); static int ngx_devpoll_set_event(ngx_event_t *ev, int event, u_int flags); +static int ngx_devpoll_process_events(ngx_log_t *log); + +static void *ngx_devpoll_create_conf(ngx_pool_t *pool); +static char *ngx_devpoll_init_conf(ngx_pool_t *pool, void *conf); /* STUB */ #define DEVPOLL_NCHANGES 512 #define DEVPOLL_NEVENTS 512 -/* should be per-thread */ static int dp; static struct pollfd *change_list, *event_list; -static unsigned int nchanges; +static u_int nchanges, max_changes; static int nevents; static ngx_event_t **change_index; -static ngx_event_t *timer_queue; -/* */ + +static ngx_str_t devpoll_name = ngx_string("/dev/poll"); + +static ngx_command_t ngx_devpoll_commands[] = { + + {ngx_string("devpoll_changes"), + NGX_EVENT_CONF|NGX_CONF_TAKE1, + ngx_conf_set_num_slot, + 0, + offsetof(ngx_devpoll_conf_t, changes), + NULL}, + + {ngx_string("devpoll_events"), + NGX_EVENT_CONF|NGX_CONF_TAKE1, + ngx_conf_set_num_slot, + 0, + offsetof(ngx_devpoll_conf_t, events), + NULL}, + + {ngx_string(""), 0, NULL, 0, 0, NULL} +}; -int ngx_devpoll_init(int max_connections, ngx_log_t *log) -{ - int change_size, event_size; +ngx_event_module_t ngx_devpoll_module_ctx = { + NGX_EVENT_MODULE, + &devpoll_name, + ngx_devpoll_create_conf, /* create configuration */ + ngx_devpoll_init_conf, /* init configuration */ + + { + ngx_devpoll_add_event, /* add an event */ + ngx_devpoll_del_event, /* delete an event */ + ngx_devpoll_add_event, /* enable an event */ + ngx_devpoll_del_event, /* disable an event */ + NULL, /* add an connection */ + NULL, /* delete an connection */ + ngx_devpoll_process_events, /* process the events */ + ngx_devpoll_init, /* init the events */ + ngx_devpoll_done, /* done the events */ + } + +}; - nevents = DEVPOLL_NEVENTS; +ngx_module_t ngx_devpoll_module = { + &ngx_devpoll_module_ctx, /* module context */ + 0, /* module index */ + ngx_devpoll_commands, /* module directives */ + NGX_EVENT_MODULE_TYPE, /* module type */ + NULL /* init module */ +}; + + +static int ngx_devpoll_init(ngx_log_t *log) +{ + ngx_devpoll_conf_t *dpcf; + + dpcf = ngx_event_get_conf(ngx_devpoll_module_ctx); + +ngx_log_debug(log, "CH: %d" _ dpcf->changes); +ngx_log_debug(log, "EV: %d" _ dpcf->events); + + max_changes = dpcf->changes; + nevents = dpcf->events; nchanges = 0; - change_size = sizeof(struct pollfd) * DEVPOLL_NCHANGES; - event_size = sizeof(struct pollfd) * DEVPOLL_NEVENTS; dp = open("/dev/poll", O_RDWR); @@ -50,29 +125,45 @@ int ngx_devpoll_init(int max_connections return NGX_ERROR; } - ngx_test_null(change_list, ngx_alloc(change_size, log), NGX_ERROR); - ngx_test_null(event_list, ngx_alloc(event_size, log), NGX_ERROR); - ngx_test_null(change_index, - ngx_alloc(sizeof(ngx_event_t *) * DEVPOLL_NCHANGES, log), + ngx_test_null(change_list, + ngx_alloc(sizeof(struct pollfd) * dpcf->changes, log), NGX_ERROR); - timer_queue = ngx_event_init_timer(log); - if (timer_queue == NULL) { + ngx_test_null(event_list, + ngx_alloc(sizeof(struct pollfd) * dpcf->events, log), + NGX_ERROR); + + ngx_test_null(change_index, + ngx_alloc(sizeof(ngx_event_t *) * dpcf->changes, log), + NGX_ERROR); + + if (ngx_event_timer_init(log) == NGX_ERROR) { return NGX_ERROR; } -#if !(USE_DEVPOLL) - ngx_event_actions.add = ngx_devpoll_add_event; - ngx_event_actions.del = ngx_devpoll_del_event; - ngx_event_actions.timer = ngx_event_add_timer; - ngx_event_actions.process = ngx_devpoll_process_events; -#endif + ngx_event_actions = ngx_devpoll_module_ctx.actions; + ngx_event_flags = NGX_HAVE_LEVEL_EVENT|NGX_USE_LEVEL_EVENT; return NGX_OK; } -int ngx_devpoll_add_event(ngx_event_t *ev, int event, u_int flags) +static void ngx_devpoll_done(ngx_log_t *log) +{ + if (close(dp) == -1) { + ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "close(/dev/poll) failed"); + } + + ngx_event_timer_done(log); + + ngx_free(change_list); + ngx_free(event_list); + ngx_free(change_index); + +} + + +static int ngx_devpoll_add_event(ngx_event_t *ev, int event, u_int flags) { #if (NGX_DEBUG_EVENT) ngx_connection_t *c = (ngx_connection_t *) ev->data; @@ -94,13 +185,11 @@ int ngx_devpoll_add_event(ngx_event_t *e #endif ev->active = 1; - ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1: 0; - return ngx_devpoll_set_event(ev, event, 0); } -int ngx_devpoll_del_event(ngx_event_t *ev, int event, u_int flags) +static int ngx_devpoll_del_event(ngx_event_t *ev, int event, u_int flags) { ngx_event_t *e; @@ -143,14 +232,14 @@ static int ngx_devpoll_set_event(ngx_eve int n; ngx_connection_t *c; - c = (ngx_connection_t *) ev->data; + c = ev->data; #if (NGX_DEBUG_EVENT) ngx_log_debug(ev->log, "devpoll fd:%d event:%d flush:%d" _ c->fd _ event _ flags); #endif - if (nchanges >= DEVPOLL_NCHANGES) { + if (nchanges >= max_changes) { ngx_log_error(NGX_LOG_WARN, ev->log, 0, "/dev/pool change list is filled up"); @@ -266,15 +355,7 @@ int ngx_devpoll_process_events(ngx_log_t } c->read->ready = 1; - - if (c->read->oneshot) { - ngx_del_timer(c->read); - ngx_devpoll_del_event(c->read, NGX_READ_EVENT, 0); - } - - if (c->read->event_handler(c->read) == NGX_ERROR) { - c->read->close_handler(c->read); - } + c->read->event_handler(c->read); } if (event_list[i].revents & POLLOUT) { @@ -283,15 +364,7 @@ int ngx_devpoll_process_events(ngx_log_t } c->write->ready = 1; - - if (c->write->oneshot) { - ngx_del_timer(c->write); - ngx_devpoll_del_event(c->write, NGX_WRITE_EVENT, 0); - } - - if (c->write->event_handler(c->write) == NGX_ERROR) { - c->write->close_handler(c->write); - } + c->write->event_handler(c->write); } if (event_list[i].revents & (POLLERR|POLLHUP|POLLNVAL)) { @@ -308,3 +381,28 @@ int ngx_devpoll_process_events(ngx_log_t return NGX_OK; } + + +static void *ngx_devpoll_create_conf(ngx_pool_t *pool) +{ + ngx_devpoll_conf_t *dpcf; + + ngx_test_null(dpcf, ngx_palloc(pool, sizeof(ngx_devpoll_conf_t)), + NGX_CONF_ERROR); + + dpcf->changes = NGX_CONF_UNSET; + dpcf->events = NGX_CONF_UNSET; + + return dpcf; +} + + +static char *ngx_devpoll_init_conf(ngx_pool_t *pool, void *conf) +{ + ngx_devpoll_conf_t *dpcf = conf; + + ngx_conf_init_value(dpcf->changes, 512); + ngx_conf_init_value(dpcf->events, 512); + + return NGX_CONF_OK; +} 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 @@ -126,9 +126,7 @@ ngx_log_debug(log, "iocp ev: %08x" _ ev) ngx_log_debug(log, "iocp ev: %08x" _ ev->event_handler); - if (ev->event_handler(ev) == NGX_ERROR) { - ev->close_handler(ev); - } + ev->event_handler(ev); } return NGX_OK; diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c --- a/src/event/modules/ngx_kqueue_module.c +++ b/src/event/modules/ngx_kqueue_module.c @@ -147,7 +147,7 @@ static int ngx_kqueue_add_event(ngx_even ngx_connection_t *c; ev->active = 1; - ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1: 0; + ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1 : 0; if (nchanges > 0 && ev->index < nchanges 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 @@ -1,63 +1,114 @@ + +/* + * Copyright (C) 2002-2003 Igor Sysoev, http://sysoev.ru + */ + #include #include -#include -#include -#include -#include #include #include -#include -#include -/* should be per-thread */ +static int ngx_poll_init(ngx_log_t *log); +static void ngx_poll_done(ngx_log_t *log); +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); + + static struct pollfd *event_list; static u_int nevents; static ngx_event_t **event_index; static ngx_event_t **ready_index; -static ngx_event_t *timer_queue; -/* */ + + +static ngx_str_t poll_name = ngx_string("poll"); + +ngx_event_module_t ngx_poll_module_ctx = { + NGX_EVENT_MODULE, + &poll_name, + NULL, /* create configuration */ + NULL, /* init configuration */ -int ngx_poll_init(int max_connections, ngx_log_t *log) + { + ngx_poll_add_event, /* add an event */ + ngx_poll_del_event, /* delete an event */ + ngx_poll_add_event, /* enable an event */ + ngx_poll_del_event, /* disable an event */ + NULL, /* add an connection */ + NULL, /* delete an connection */ + ngx_poll_process_events, /* process the events */ + ngx_poll_init, /* init the events */ + ngx_poll_done /* done the events */ + } + +}; + +ngx_module_t ngx_poll_module = { + &ngx_poll_module_ctx, /* module context */ + 0, /* module index */ + NULL, /* module directives */ + NGX_EVENT_MODULE_TYPE, /* module type */ + NULL /* init module */ +}; + + + +static int ngx_poll_init(ngx_log_t *log) { + ngx_event_conf_t *ecf; + + ecf = ngx_event_get_conf(ngx_event_module_ctx); + ngx_test_null(event_list, - ngx_alloc(sizeof(struct pollfd) * max_connections, log), + ngx_alloc(sizeof(struct pollfd) * ecf->connections, log), NGX_ERROR); ngx_test_null(event_index, - ngx_alloc(sizeof(ngx_event_t *) * max_connections, log), + ngx_alloc(sizeof(ngx_event_t *) * ecf->connections, log), NGX_ERROR); ngx_test_null(ready_index, - ngx_alloc(sizeof(ngx_event_t *) * 2 * max_connections, log), + ngx_alloc(sizeof(ngx_event_t *) * 2 * ecf->connections, log), NGX_ERROR); nevents = 0; - timer_queue = ngx_event_init_timer(log); - if (timer_queue == NULL) { + if (ngx_event_timer_init(log) == NGX_ERROR) { return NGX_ERROR; } - ngx_event_actions.add = ngx_poll_add_event; - ngx_event_actions.del = ngx_poll_del_event; - ngx_event_actions.timer = ngx_event_add_timer; - ngx_event_actions.process = ngx_poll_process_events; + ngx_event_actions = ngx_poll_module_ctx.actions; + + ngx_event_flags = NGX_HAVE_LEVEL_EVENT + |NGX_HAVE_ONESHOT_EVENT + |NGX_USE_LEVEL_EVENT; return NGX_OK; } -int ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags) + +static void ngx_poll_done(ngx_log_t *log) +{ + ngx_event_timer_done(log); + + ngx_free(event_list); + ngx_free(event_index); + ngx_free(ready_index); +} + + +static int ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags) { ngx_event_t *e; ngx_connection_t *c; - c = (ngx_connection_t *) ev->data; + c = ev->data; ev->active = 1; - ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1: 0; + ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1 : 0; if (event == NGX_READ_EVENT) { e = c->write; @@ -93,7 +144,8 @@ int ngx_poll_add_event(ngx_event_t *ev, return NGX_OK; } -int ngx_poll_del_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) { ngx_event_t *e; ngx_connection_t *c; @@ -138,7 +190,8 @@ int ngx_poll_del_event(ngx_event_t *ev, return NGX_OK; } -int ngx_poll_process_events(ngx_log_t *log) + +static int ngx_poll_process_events(ngx_log_t *log) { int ready, found; u_int i, nready; @@ -202,33 +255,38 @@ int ngx_poll_process_events(ngx_log_t *l found = 0; - if (event_list[i].revents & POLLIN) { + if (event_list[i].revents & POLLNVAL) { + ngx_log_error(NGX_LOG_ALERT, log, EBADF, + "poll() error on %d", event_list[i].fd); + continue; + } + + if (event_list[i].revents & POLLIN + || (event_list[i].revents & (POLLERR|POLLHUP) + && c->read->active)) + { found = 1; ready_index[nready++] = c->read; } - if (event_list[i].revents & POLLOUT) { + if (event_list[i].revents & POLLOUT + || (event_list[i].revents & (POLLERR|POLLHUP) + && c->write->active)) + { found = 1; ready_index[nready++] = c->write; } - if (event_list[i].revents & (POLLERR|POLLHUP|POLLNVAL)) { - found = 1; - - /* need ot add to ready_index[nready++] = c->read or c->write; */ - - err = 0; - if (event_list[i].revents & POLLNVAL) { - err = EBADF; - } - - ngx_log_error(NGX_LOG_ERR, log, err, - "poll() error on %d:%d", - event_list[i].fd, event_list[i].revents); + if (found) { + ready--; + continue; } - if (found) { - ready--; + if (event_list[i].revents & (POLLERR|POLLHUP)) { + ngx_log_error(NGX_LOG_ALERT, log, 0, + "strange poll() error on %d:%d:%d", + event_list[i].fd, + event_list[i].events, event_list[i].revents); } } diff --git a/src/event/modules/ngx_select_module.c b/src/event/modules/ngx_select_module.c --- a/src/event/modules/ngx_select_module.c +++ b/src/event/modules/ngx_select_module.c @@ -109,6 +109,8 @@ static int ngx_select_init(ngx_log_t *lo static void ngx_select_done(ngx_log_t *log) { + ngx_event_timer_done(log); + ngx_free(event_index); ngx_free(ready_index); } @@ -149,19 +151,21 @@ static int ngx_select_add_event(ngx_even max_write++; } #else - if (event == NGX_READ_EVENT) + if (event == NGX_READ_EVENT) { FD_SET(c->fd, &master_read_fd_set); - else if (event == NGX_WRITE_EVENT) + } else if (event == NGX_WRITE_EVENT) { FD_SET(c->fd, &master_write_fd_set); + } - if (max_fd != -1 && max_fd < c->fd) + if (max_fd != -1 && max_fd < c->fd) { max_fd = c->fd; + } #endif ev->active = 1; - ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1: 0; + ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1 : 0; event_index[nevents] = ev; ev->index = nevents; @@ -177,14 +181,16 @@ static int ngx_select_del_event(ngx_even c = ev->data; - if (ev->index == NGX_INVALID_INDEX) + if (ev->index == NGX_INVALID_INDEX) { return NGX_OK; + } #if (NGX_DEBUG_EVENT) ngx_log_debug(c->log, "del event: %d, %d" _ c->fd _ event); #endif #if (WIN32) + if (event == NGX_READ_EVENT) { FD_CLR(c->fd, &master_read_fd_set); max_read--; @@ -193,15 +199,20 @@ static int ngx_select_del_event(ngx_even FD_CLR(c->fd, &master_write_fd_set); max_write--; } + #else - if (event == NGX_READ_EVENT) + + if (event == NGX_READ_EVENT) { FD_CLR(c->fd, &master_read_fd_set); - else if (event == NGX_WRITE_EVENT) + } else if (event == NGX_WRITE_EVENT) { FD_CLR(c->fd, &master_write_fd_set); + } - if (max_fd == c->fd) + if (max_fd == c->fd) { max_fd = -1; + } + #endif if (ev->index < --nevents) { @@ -246,8 +257,9 @@ static int ngx_select_process_events(ngx if (max_fd == -1) { for (i = 0; i < nevents; i++) { c = (ngx_connection_t *) event_index[i]->data; - if (max_fd < c->fd) + if (max_fd < c->fd) { max_fd = c->fd; + } } #if (NGX_DEBUG_EVENT) @@ -344,10 +356,11 @@ static int ngx_select_process_events(ngx ev->timer_set = 0; } - if (ev->write) + if (ev->write) { ngx_select_del_event(ev, NGX_WRITE_EVENT, 0); - else + } else { ngx_select_del_event(ev, NGX_READ_EVENT, 0); + } } ev->event_handler(ev); diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -1,31 +1,25 @@ #include #include -#include -#include -#include -#include -#include #include #include #include -#include + + +#define DEF_CONNECTIONS 1024 + extern ngx_event_module_t ngx_select_module_ctx; -#if (HAVE_POLL) -#include -#endif - -#if (HAVE_DEVPOLL) -#include -#endif - #if (HAVE_KQUEUE) extern ngx_event_module_t ngx_kqueue_module_ctx; #include #endif +#if (HAVE_DEVPOLL) +extern ngx_event_module_t ngx_devpoll_module_ctx; +#endif + #if (HAVE_AIO) #include #endif @@ -259,7 +253,6 @@ static char *ngx_events_block(ngx_conf_t char *rv; void ***ctx; ngx_conf_t pcf; - ngx_event_conf_t *ecf; ngx_event_module_t *module; /* count the number of the event modules and set up their indices */ @@ -364,6 +357,7 @@ static void *ngx_event_create_conf(ngx_p NGX_CONF_ERROR); ecf->connections = NGX_CONF_UNSET; + ecf->timer_queues = NGX_CONF_UNSET; ecf->type = NGX_CONF_UNSET; return ecf; @@ -376,13 +370,27 @@ static char *ngx_event_init_conf(ngx_poo #if (HAVE_KQUEUE) - ngx_conf_init_value(ecf->connections, 1024); +#if 0 + if (ecf->connections != NGX_CONF_UNSET) { + ecf->connections = (ngx_max_connections < DEF_CONNECTIONS) ? + ngx_max_connections : DEF_CONNECTIONS; + + } else if (ecf->connections > ngx_max_connections) { + } +#endif + + ngx_conf_init_value(ecf->connections, DEF_CONNECTIONS); ngx_conf_init_value(ecf->type, ngx_kqueue_module_ctx.index); +#elif (HAVE_DEVPOLL) + + ngx_conf_init_value(ecf->connections, DEF_CONNECTIONS); + ngx_conf_init_value(ecf->type, ngx_devpoll_module_ctx.index); + #else /* HAVE_SELECT */ ngx_conf_init_value(ecf->connections, - FD_SETSIZE < 1024 ? FD_SETSIZE : 1024); + FD_SETSIZE < DEF_CONNECTIONS ? FD_SETSIZE : DEF_CONNECTIONS); ngx_conf_init_value(ecf->type, ngx_select_module_ctx.index); 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 @@ -3,6 +3,9 @@ #include +#include + +#if 0 #include #include #include @@ -10,6 +13,7 @@ #include #include #include +#endif @@ -19,7 +23,9 @@ #define NGX_INVALID_INDEX 0x80000000 +#if 0 typedef struct ngx_event_s ngx_event_t; +#endif #if (HAVE_IOCP) typedef struct { @@ -125,6 +131,7 @@ struct ngx_event_s { }; +#if 1 typedef enum { NGX_SELECT_EVENT_N = 0, #if (HAVE_POLL) @@ -144,7 +151,7 @@ typedef enum { #endif NGX_DUMMY_EVENT_N /* avoid comma at end of enumerator list */ } ngx_event_type_e ; - +#endif typedef struct { @@ -165,18 +172,18 @@ typedef struct { /* The event filter requires to read/write the whole data - select, poll, /dev/poll, kqueue. */ -#define NGX_HAVE_LEVEL_EVENT 1 +#define NGX_HAVE_LEVEL_EVENT 0x00000001 /* The event filter is deleted after a notification without an additional syscall - select, poll, kqueue. */ -#define NGX_HAVE_ONESHOT_EVENT 2 +#define NGX_HAVE_ONESHOT_EVENT 0x00000002 /* The event filter notifies only the changes and an initial level - kqueue */ -#define NGX_HAVE_CLEAR_EVENT 4 +#define NGX_HAVE_CLEAR_EVENT 0x00000004 /* The event filter has kqueue features - the eof flag, errno, available data, etc */ -#define NGX_HAVE_KQUEUE_EVENT 8 +#define NGX_HAVE_KQUEUE_EVENT 0x00000008 /* The event filter supports low water mark - kqueue's NOTE_LOWAT. kqueue in FreeBSD 4.1-4.2 has no NOTE_LOWAT so we need a separate flag */ @@ -207,6 +214,7 @@ typedef struct { kqueue: kqueue deletes event filters for file that closed so we need only to delete filters in user-level batch array /dev/poll: we need to flush POLLREMOVE event before closing file */ + #define NGX_CLOSE_EVENT 1 @@ -215,9 +223,6 @@ typedef struct { #define NGX_READ_EVENT EVFILT_READ #define NGX_WRITE_EVENT EVFILT_WRITE -#define NGX_ENABLE_EVENT EV_ENABLE -#define NGX_DISABLE_EVENT EV_DISABLE - /* NGX_CLOSE_EVENT is the module flag and it would not go into a kernel so we need to choose the value that would not interfere with any existent and future flags. kqueue has such values - EV_FLAG1, EV_EOF and EV_ERROR. @@ -252,6 +257,10 @@ typedef struct { #endif /* HAVE_KQUEUE */ +#ifndef NGX_CLEAR_EVENT +#define NGX_CLEAR_EVENT 0 /* dummy */ +#endif + #if (USE_KQUEUE) #define ngx_init_events ngx_kqueue_init @@ -317,8 +326,8 @@ extern int ngx_event_f typedef struct { int connections; + int timer_queues; int type; - int timer_queues; } ngx_event_conf_t; diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c --- a/src/event/ngx_event_accept.c +++ b/src/event/ngx_event_accept.c @@ -32,6 +32,11 @@ void ngx_event_accept(ngx_event_t *ev) #endif do { + + /* Create the pool before accept() to avoid copy the sockaddr. + Although accept() can fail it's uncommon case + and the pool can be got from the free pool list */ + pool = ngx_create_pool(ls->pool_size, ev->log); if (pool == NULL) { return; diff --git a/src/event/ngx_event_acceptex.c b/src/event/ngx_event_acceptex.c --- a/src/event/ngx_event_acceptex.c +++ b/src/event/ngx_event_acceptex.c @@ -104,14 +104,10 @@ int ngx_event_post_acceptex(ngx_listen_t c->unexpected_eof = 1; wev->write = 1; - rev->first = wev->first = 1; c->handler = ls->handler; rev->event_handler = ngx_event_acceptex; - wev->timer_handler = rev->timer_handler = ngx_event_close_connection; - wev->close_handler = rev->close_handler = ngx_event_close_connection; - c->ctx = ls->ctx; c->servers = ls->servers; diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -500,7 +500,7 @@ static char *ngx_http_block(ngx_conf_t * /* prepare for the next cycle */ - in_port[p].addrs.elts += in_port[p].addrs.size; + (char *) in_port[p].addrs.elts += in_port[p].addrs.size; in_port[p].addrs.nelts--; in_addr = (ngx_http_in_addr_t *) in_port[p].addrs.elts; diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -267,7 +267,6 @@ void ngx_http_handler(ngx_http_request_t { int rc, i; ngx_http_handler_pt *h; - ngx_http_module_t *module; ngx_http_core_loc_conf_t *lcf, **lcfp; ngx_http_core_srv_conf_t *scf; @@ -349,7 +348,7 @@ ngx_log_debug(r->connection->log, "trans int ngx_http_core_translate_handler(ngx_http_request_t *r) { - int i, rc, len, port_len, f_offset, l_offset; + int len, port_len, f_offset, l_offset; char *buf, *location, *last; ngx_err_t err; ngx_table_elt_t *h; @@ -623,7 +622,7 @@ static int ngx_http_core_init(ngx_pool_t static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy) { - int i, j; + int m; char *rv; ngx_http_module_t *module; ngx_conf_t pcf; @@ -650,12 +649,12 @@ static char *ngx_server_block(ngx_conf_t ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module), NGX_CONF_ERROR); - for (i = 0; ngx_modules[i]; i++) { - if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) { + for (m = 0; ngx_modules[m]; m++) { + if (ngx_modules[m]->type != NGX_HTTP_MODULE_TYPE) { continue; } - module = (ngx_http_module_t *) ngx_modules[i]->ctx; + module = (ngx_http_module_t *) ngx_modules[m]->ctx; if (module->create_srv_conf) { ngx_test_null(ctx->srv_conf[module->index], @@ -995,8 +994,8 @@ static char *ngx_set_listen(ngx_conf_t * { ngx_http_core_srv_conf_t *scf = (ngx_http_core_srv_conf_t *) conf; - uint p; char *addr; + u_int p; ngx_str_t *args; ngx_http_listen_t *ls; diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -73,7 +73,7 @@ typedef struct { #define ngx_http_types_hash_key(key, ext) \ { \ - uint n; \ + u_int n; \ for (key = 0, n = 0; n < ext.len; n++) { \ key += ext.data[n]; \ } \ diff --git a/src/http/ngx_http_event.c b/src/http/ngx_http_event.c --- a/src/http/ngx_http_event.c +++ b/src/http/ngx_http_event.c @@ -695,8 +695,7 @@ static ssize_t ngx_http_read_request_hea void ngx_http_finalize_request(ngx_http_request_t *r, int error) { - int rc, event; - ngx_msec_t timeout; + int rc; ngx_event_t *rev, *wev; rc = error; @@ -794,7 +793,6 @@ void ngx_http_set_write_handler(ngx_http static void ngx_http_writer(ngx_event_t *wev) { int rc; - ngx_msec_t timeout; ngx_event_t *rev; ngx_connection_t *c; ngx_http_request_t *r; diff --git a/src/os/unix/ngx_daemon.c b/src/os/unix/ngx_daemon.c --- a/src/os/unix/ngx_daemon.c +++ b/src/os/unix/ngx_daemon.c @@ -11,7 +11,7 @@ int ngx_daemon(ngx_log_t *log) switch (fork()) { case -1: - ngx_log_error(NGX_LOG_ALERT, log, errno, "fork() failed"); + ngx_log_error(NGX_LOG_EMERG, log, errno, "fork() failed"); return NGX_ERROR; case 0: @@ -22,7 +22,7 @@ int ngx_daemon(ngx_log_t *log) } if (setsid() == -1) { - ngx_log_error(NGX_LOG_ALERT, log, errno, "setsid() failed"); + ngx_log_error(NGX_LOG_EMERG, log, errno, "setsid() failed"); return NGX_ERROR; } @@ -32,7 +32,7 @@ int ngx_daemon(ngx_log_t *log) switch (fork()) { case -1: - ngx_log_error(NGX_LOG_ALERT, log, errno, "fork() failed"); + ngx_log_error(NGX_LOG_EMERG, log, errno, "fork() failed"); return NGX_ERROR; case 0: @@ -49,28 +49,28 @@ int ngx_daemon(ngx_log_t *log) #if 0 fd = open("/dev/null", O_RDWR); if (fd == -1) { - ngx_log_error(NGX_LOG_ALERT, log, errno, "open(\"/dev/null\") failed"); + ngx_log_error(NGX_LOG_EMERG, log, errno, "open(\"/dev/null\") failed"); return NGX_ERROR; } if (dup2(fd, STDIN_FILENO) == -1) { - ngx_log_error(NGX_LOG_ALERT, log, errno, "dup2(STDIN) failed"); + ngx_log_error(NGX_LOG_EMERG, log, errno, "dup2(STDIN) failed"); return NGX_ERROR; } if (dup2(fd, STDOUT_FILENO) == -1) { - ngx_log_error(NGX_LOG_ALERT, log, errno, "dup2(STDOUT) failed"); + ngx_log_error(NGX_LOG_EMERG, log, errno, "dup2(STDOUT) failed"); return NGX_ERROR; } if (dup2(fd, STDERR_FILENO) == -1) { - ngx_log_error(NGX_LOG_ALERT, log, errno, "dup2(STDERR) failed"); + ngx_log_error(NGX_LOG_EMERG, log, errno, "dup2(STDERR) failed"); return NGX_ERROR; } if (fd > STDERR_FILENO) { if (close(fd) == -1) { - ngx_log_error(NGX_LOG_ALERT, log, errno, "close() failed"); + ngx_log_error(NGX_LOG_EMERG, log, errno, "close() failed"); return NGX_ERROR; } } diff --git a/src/os/unix/ngx_freebsd_init.h b/src/os/unix/ngx_freebsd_init.h --- a/src/os/unix/ngx_freebsd_init.h +++ b/src/os/unix/ngx_freebsd_init.h @@ -4,8 +4,6 @@ #include #include -#include -#include #include diff --git a/src/os/unix/ngx_unix_init.c b/src/os/unix/ngx_unix_init.c --- a/src/os/unix/ngx_unix_init.c +++ b/src/os/unix/ngx_unix_init.c @@ -3,6 +3,9 @@ #include +int ngx_max_sockets; + + int ngx_unix_init(ngx_log_t *log) { struct sigaction sa; @@ -29,11 +32,32 @@ int ngx_unix_init(ngx_log_t *log) "getrlimit(RLIMIT_NOFILE): %qd:%qd", rlmt.rlim_cur, rlmt.rlim_max); - -#if 0 - RLIM_INFINITY - max_connections =< rlmt.rlim_cur; -#endif + ngx_max_sockets = rlmt.rlim_cur; return NGX_OK; } + + +int ngx_unix_post_conf_init(ngx_log_t *log) +{ + ngx_fd_t pp[2]; + + if (pipe(pp) == -1) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "pipe() failed"); + return NGX_ERROR; + } + + if (dup2(pp[1], STDERR_FILENO) == -1) { + ngx_log_error(NGX_LOG_EMERG, log, errno, "dup2(STDERR) failed"); + return NGX_ERROR; + } + + if (pp[1] > STDERR_FILENO) { + if (close(pp[1]) == -1) { + ngx_log_error(NGX_LOG_EMERG, log, errno, "close() failed"); + return NGX_ERROR; + } + } + + return NGX_OK; +} diff --git a/src/os/win32/ngx_files.h b/src/os/win32/ngx_files.h --- a/src/os/win32/ngx_files.h +++ b/src/os/win32/ngx_files.h @@ -36,6 +36,9 @@ FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE, \ NULL); +#define ngx_open_tempfile_n "CreateFile()" + + #define ngx_open_file_n "CreateFile()" diff --git a/src/os/win32/ngx_init.c b/src/os/win32/ngx_init.c --- a/src/os/win32/ngx_init.c +++ b/src/os/win32/ngx_init.c @@ -1,9 +1,29 @@ -#include +#include +#include + + +int ngx_max_sockets; + + +ngx_os_io_t ngx_os_io = { +#if 0 + ngx_unix_recv, + NULL, + NULL, + ngx_freebsd_write_chain +#else + NULL, + NULL, + NULL, + NULL +#endif +}; + int ngx_os_init(ngx_log_t *log) { - if (ngx_init_sockets(&ngx_log) == NGX_ERROR) { + if (ngx_init_sockets(log) == NGX_ERROR) { return NGX_ERROR; }