From 9e58019dc287493e02543d614c975cc14295a71e Mon Sep 17 00:00:00 2001 From: Igor Sysoev Date: Wed, 1 Feb 2006 18:22:15 +0000 Subject: [PATCH] nginx-0.3.24-RELEASE import *) Workaround: for bug in FreeBSD kqueue. *) Bugfix: now a response generated by the "post_action" directive is not transferred to a client. *) Bugfix: the memory leaks were occurring if many log files were used. *) Bugfix: the first "proxy_redirect" directive was working inside one location. *) Bugfix: on 64-bit platforms segmentation fault may occurred on start if the many names were used in the "server_name" directives; the bug had appeared in 0.3.18. --- auto/sources | 7 +- docs/xml/nginx/changes.xml | 55 ++++++++++ src/core/nginx.h | 2 +- src/core/ngx_array.c | 12 ++- src/core/ngx_conf_file.c | 17 +-- src/core/ngx_config.h | 3 +- src/core/ngx_connection.c | 2 - src/core/ngx_core.h | 2 +- src/core/ngx_cycle.c | 89 +++++++++++----- src/core/ngx_cycle.h | 7 ++ src/core/ngx_palloc.c | 40 +++++++ src/core/ngx_palloc.h | 4 + src/event/ngx_event.c | 17 +-- src/event/ngx_event_busy_lock.c | 2 +- src/http/modules/ngx_http_proxy_module.c | 2 +- src/http/ngx_http_core_module.c | 25 +++-- src/http/ngx_http_request.c | 2 + src/os/unix/ngx_readv_chain.c | 15 +++ src/os/unix/ngx_recv.c | 15 +++ src/os/unix/ngx_shared.c | 95 ----------------- src/os/unix/ngx_shmem.c | 123 ++++++++++++++++++++++ src/os/unix/{ngx_shared.h => ngx_shmem.h} | 10 +- src/os/win32/ngx_shared.h | 18 ---- src/os/win32/ngx_shmem.c | 58 ++++++++++ src/os/win32/ngx_shmem.h | 27 +++++ 25 files changed, 463 insertions(+), 186 deletions(-) delete mode 100644 src/os/unix/ngx_shared.c create mode 100644 src/os/unix/ngx_shmem.c rename src/os/unix/{ngx_shared.h => ngx_shmem.h} (52%) delete mode 100644 src/os/win32/ngx_shared.h create mode 100644 src/os/win32/ngx_shmem.c create mode 100644 src/os/win32/ngx_shmem.h diff --git a/auto/sources b/auto/sources index 5ffbc6c98..5dac1995f 100644 --- a/auto/sources +++ b/auto/sources @@ -119,7 +119,7 @@ UNIX_DEPS="$CORE_DEPS $EVENT_DEPS \ src/os/unix/ngx_alloc.h \ src/os/unix/ngx_files.h \ src/os/unix/ngx_channel.h \ - src/os/unix/ngx_shared.h \ + src/os/unix/ngx_shmem.h \ src/os/unix/ngx_process.h \ src/os/unix/ngx_setproctitle.h \ src/os/unix/ngx_atomic.h \ @@ -152,7 +152,7 @@ UNIX_SRCS="$CORE_SRCS $EVENT_SRCS \ src/os/unix/ngx_send.c \ src/os/unix/ngx_writev_chain.c \ src/os/unix/ngx_channel.c \ - src/os/unix/ngx_shared.c \ + src/os/unix/ngx_shmem.c \ src/os/unix/ngx_process.c \ src/os/unix/ngx_daemon.c \ src/os/unix/ngx_setproctitle.c \ @@ -190,7 +190,7 @@ WIN32_DEPS="$CORE_DEPS $EVENT_DEPS \ src/os/win32/ngx_errno.h \ src/os/win32/ngx_alloc.h \ src/os/win32/ngx_files.h \ - src/os/win32/ngx_shared.h \ + src/os/win32/ngx_shmem.h \ src/os/win32/ngx_process.h \ src/os/win32/ngx_atomic.h \ src/os/win32/ngx_thread.h \ @@ -207,6 +207,7 @@ WIN32_SRCS="$CORE_SRCS $EVENT_SRCS \ src/os/win32/ngx_errno.c \ src/os/win32/ngx_alloc.c \ src/os/win32/ngx_files.c \ + src/os/win32/ngx_shmem.c \ src/os/win32/ngx_time.c \ src/os/win32/ngx_process.c \ src/os/win32/ngx_thread.c \ diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml index 72eb87951..7ef4dbf97 100644 --- a/docs/xml/nginx/changes.xml +++ b/docs/xml/nginx/changes.xml @@ -9,6 +9,61 @@ nginx changelog + + + + +обход ошибки в kqueue во FreeBSD. + + +for bug in FreeBSD kqueue. + + + + + +ответ, создаваемый директивой post_action, теперь не передаётся клиенту. + + +now a response generated by the "post_action" directive is not transferred +to a client. + + + + + +при использовании большого количества лог-файлов происходила утечка памяти. + + +the memory leaks were occuring if many log files were used. + + + + + +внтури одного location работала только первая директива proxy_redirect. + + +the first "proxy_redirect" directive was working inside one location. + + + + + +на 64-битных платформах при старте мог произойти segmentation fault, +если использовалось большое количиство имён в директивах server_name; +ошибка появилась в 0.3.18. + + +on 64-bit platforms segmentation fault may occurred on start +if the many names were used in the "server_name" directives; +bug appeared in 0.3.18. + + + + + + diff --git a/src/core/nginx.h b/src/core/nginx.h index 0912ac5cd..c2f9737a7 100644 --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -8,7 +8,7 @@ #define _NGINX_H_INCLUDED_ -#define NGINX_VER "nginx/0.3.23" +#define NGINX_VER "nginx/0.3.24" #define NGINX_VAR "NGINX" #define NGX_OLDPID_EXT ".oldbin" diff --git a/src/core/ngx_array.c b/src/core/ngx_array.c index b6167afc4..1b9f7cb78 100644 --- a/src/core/ngx_array.c +++ b/src/core/ngx_array.c @@ -8,7 +8,8 @@ #include -ngx_array_t *ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size) +ngx_array_t * +ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size) { ngx_array_t *a; @@ -31,7 +32,8 @@ ngx_array_t *ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size) } -void ngx_array_destroy(ngx_array_t *a) +void +ngx_array_destroy(ngx_array_t *a) { ngx_pool_t *p; @@ -47,7 +49,8 @@ void ngx_array_destroy(ngx_array_t *a) } -void *ngx_array_push(ngx_array_t *a) +void * +ngx_array_push(ngx_array_t *a) { void *elt, *new; size_t size; @@ -92,7 +95,8 @@ void *ngx_array_push(ngx_array_t *a) } -void *ngx_array_push_n(ngx_array_t *a, ngx_uint_t n) +void * +ngx_array_push_n(ngx_array_t *a, ngx_uint_t n) { void *elt, *new; size_t size; diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c index 589eb0e00..ab097c049 100644 --- a/src/core/ngx_conf_file.c +++ b/src/core/ngx_conf_file.c @@ -670,20 +670,9 @@ ngx_conf_full_name(ngx_cycle_t *cycle, ngx_str_t *name) name->len = cycle->root.len + old.len; - if (cycle->connections) { - name->data = ngx_palloc(cycle->pool, name->len + 1); - if (name->data == NULL) { - return NGX_ERROR; - } - - } else { - - /* the init_cycle */ - - name->data = ngx_alloc(name->len + 1, cycle->log); - if (name->data == NULL) { - return NGX_ERROR; - } + name->data = ngx_palloc(cycle->pool, name->len + 1); + if (name->data == NULL) { + return NGX_ERROR; } p = ngx_cpymem(name->data, cycle->root.data, cycle->root.len), diff --git a/src/core/ngx_config.h b/src/core/ngx_config.h index d924ec5e8..6078d89c7 100644 --- a/src/core/ngx_config.h +++ b/src/core/ngx_config.h @@ -99,7 +99,8 @@ typedef long ngx_flag_t; #endif #define ngx_align(d, a) (((d) + (a - 1)) & ~(a - 1)) -#define ngx_align_ptr(p, a) (u_char *) (((uintptr_t) (p) + (a - 1)) & ~(a - 1)) +#define ngx_align_ptr(p, a) \ + (u_char *) (((uintptr_t) (p) + ((uintptr_t) a - 1)) & ~((uintptr_t) a - 1)) #define ngx_abort abort diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c index 93b43c477..75604284f 100644 --- a/src/core/ngx_connection.c +++ b/src/core/ngx_connection.c @@ -722,9 +722,7 @@ ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text) || err == NGX_EPIPE #endif || err == NGX_ENOTCONN -#if !(NGX_CRIT_ETIMEDOUT) || err == NGX_ETIMEDOUT -#endif || err == NGX_ECONNREFUSED || err == NGX_EHOSTUNREACH) { diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h index 38395cb59..46e88df88 100644 --- a/src/core/ngx_core.h +++ b/src/core/ngx_core.h @@ -42,7 +42,7 @@ typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c); #include #include #include -#include +#include #include #include #include diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c index e13bcd8da..4bff82871 100644 --- a/src/core/ngx_cycle.c +++ b/src/core/ngx_cycle.c @@ -9,6 +9,7 @@ #include +static void ngx_destroy_cycle_pools(ngx_conf_t *conf); static ngx_int_t ngx_cmp_sockaddr(struct sockaddr *sa1, struct sockaddr *sa2); static void ngx_clean_old_cycles(ngx_event_t *ev); @@ -40,17 +41,18 @@ static ngx_str_t error_log = ngx_null_string; ngx_cycle_t * ngx_init_cycle(ngx_cycle_t *old_cycle) { - void *rv; - ngx_uint_t i, n, failed; - ngx_log_t *log; - ngx_conf_t conf; - ngx_pool_t *pool; - ngx_cycle_t *cycle, **old; - ngx_list_part_t *part; - ngx_open_file_t *file; - ngx_listening_t *ls, *nls; - ngx_core_conf_t *ccf; - ngx_core_module_t *module; + void *rv; + ngx_uint_t i, n, failed; + ngx_log_t *log; + ngx_conf_t conf; + ngx_pool_t *pool; + ngx_cycle_t *cycle, **old; + ngx_list_part_t *part; + ngx_open_file_t *file; + ngx_listening_t *ls, *nls; + ngx_core_conf_t *ccf; + ngx_core_module_t *module; + log = old_cycle->log; @@ -69,11 +71,20 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) cycle->pool = pool; cycle->log = log; cycle->old_cycle = old_cycle; - cycle->conf_file = old_cycle->conf_file; cycle->root.len = sizeof(NGX_PREFIX) - 1; cycle->root.data = (u_char *) NGX_PREFIX; + cycle->conf_file.len = old_cycle->conf_file.len; + cycle->conf_file.data = ngx_palloc(pool, old_cycle->conf_file.len + 1); + if (cycle->conf_file.data == NULL) { + ngx_destroy_pool(pool); + return NULL; + } + ngx_cpystrn(cycle->conf_file.data, old_cycle->conf_file.data, + old_cycle->conf_file.len + 1); + + n = old_cycle->pathes.nelts ? old_cycle->pathes.nelts : 10; cycle->pathes.elts = ngx_pcalloc(pool, n * sizeof(ngx_path_t *)); @@ -99,7 +110,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) } if (ngx_list_init(&cycle->open_files, pool, n, sizeof(ngx_open_file_t)) - == NGX_ERROR) + == NGX_ERROR) { ngx_destroy_pool(pool); return NULL; @@ -168,6 +179,22 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) return NULL; } + +#if 0 + cycle->shm.size = /* STUB */ ngx_pagesize; + cycle->shm.log = log; + + if (ngx_shm_alloc(&cycle->shm) != NGX_OK) { + ngx_destroy_pool(conf.temp_pool); + ngx_destroy_pool(pool); + return NULL; + } + + cycle->shm_last = cycle->shm.addr; + cycle->shm_end = cycle->shm.addr + cycle->shm.size; +#endif + + conf.ctx = cycle->conf_ctx; conf.cycle = cycle; conf.pool = pool; @@ -180,8 +207,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) #endif if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) { - ngx_destroy_pool(conf.temp_pool); - ngx_destroy_pool(pool); + ngx_destroy_cycle_pools(&conf); return NULL; } @@ -203,8 +229,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) if (module->init_conf(cycle, cycle->conf_ctx[ngx_modules[i]->index]) == NGX_CONF_ERROR) { - ngx_destroy_pool(conf.temp_pool); - ngx_destroy_pool(pool); + ngx_destroy_cycle_pools(&conf); return NULL; } } @@ -397,6 +422,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) } } + if (failed) { /* rollback the new cycle configuration */ @@ -429,8 +455,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) } if (ngx_test_config) { - ngx_destroy_pool(conf.temp_pool); - ngx_destroy_pool(pool); + ngx_destroy_cycle_pools(&conf); return NULL; } @@ -447,8 +472,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) } } - ngx_destroy_pool(conf.temp_pool); - ngx_destroy_pool(pool); + ngx_destroy_cycle_pools(&conf); return NULL; } @@ -533,16 +557,16 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) ngx_destroy_pool(conf.temp_pool); - if (old_cycle->connections == NULL) { - /* an old cycle is an init cycle */ + if (ngx_process == NGX_PROCESS_MASTER || ngx_is_init_cycle(old_cycle)) { + + if (old_cycle->shm.addr) { + ngx_shm_free(&old_cycle->shm); + } + ngx_destroy_pool(old_cycle->pool); return cycle; } - if (ngx_process == NGX_PROCESS_MASTER) { - ngx_destroy_pool(old_cycle->pool); - return cycle; - } if (ngx_temp_pool == NULL) { ngx_temp_pool = ngx_create_pool(128, cycle->log); @@ -586,6 +610,15 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) } +static void +ngx_destroy_cycle_pools(ngx_conf_t *conf) +{ + ngx_shm_free(&conf->cycle->shm); + ngx_destroy_pool(conf->temp_pool); + ngx_destroy_pool(conf->pool); +} + + static ngx_int_t ngx_cmp_sockaddr(struct sockaddr *sa1, struct sockaddr *sa2) { @@ -623,7 +656,7 @@ ngx_create_pidfile(ngx_cycle_t *cycle, ngx_cycle_t *old_cycle) ngx_file_t file; ngx_core_conf_t *ccf, *old_ccf; - if (!ngx_test_config && old_cycle && old_cycle->conf_ctx == NULL) { + if (!ngx_test_config && ngx_is_init_cycle(old_cycle)) { /* * do not create the pid file in the first ngx_init_cycle() call diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h index cbf8c7ba1..b29cf3495 100644 --- a/src/core/ngx_cycle.h +++ b/src/core/ngx_cycle.h @@ -32,6 +32,10 @@ struct ngx_cycle_s { ngx_connection_t *free_connections; ngx_uint_t free_connection_n; + ngx_shm_t shm; + u_char *shm_last; + u_char *shm_end; + ngx_array_t listening; ngx_array_t pathes; ngx_list_t open_files; @@ -90,6 +94,9 @@ typedef struct { } ngx_core_tls_t; +#define ngx_is_init_cycle(old) (old && old->conf_ctx == NULL) + + ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle); ngx_int_t ngx_create_pidfile(ngx_cycle_t *cycle, ngx_cycle_t *old_cycle); void ngx_delete_pidfile(ngx_cycle_t *cycle); diff --git a/src/core/ngx_palloc.c b/src/core/ngx_palloc.c index a0229b2ea..eb0e86d0a 100644 --- a/src/core/ngx_palloc.c +++ b/src/core/ngx_palloc.c @@ -221,6 +221,46 @@ ngx_pcalloc(ngx_pool_t *pool, size_t size) } +void * +ngx_shalloc(size_t size) +{ + u_char *p; + + if (size < sizeof(int) || (size & 1)) { + p = ngx_cycle->shm_last; + + } else { + p = ngx_align_ptr(ngx_cycle->shm_last, NGX_ALIGNMENT); + } + + if ((size_t) (ngx_cycle->shm_end - p) >= size) { + ngx_cycle->shm_last = p + size; + return p; + } + + ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, 0, + "allocation of %uz bytes in shared memory failed, " + "only %uz are available", + size, ngx_cycle->shm_end - ngx_cycle->shm_last); + + return NULL; +} + + +void * +ngx_shcalloc(size_t size) +{ + void *p; + + p = ngx_shalloc(size); + if (p) { + ngx_memzero(p, size); + } + + return p; +} + + ngx_pool_cleanup_t * ngx_pool_cleanup_add(ngx_pool_t *p, size_t size) { diff --git a/src/core/ngx_palloc.h b/src/core/ngx_palloc.h index 239728102..85e77f50d 100644 --- a/src/core/ngx_palloc.h +++ b/src/core/ngx_palloc.h @@ -71,6 +71,10 @@ void *ngx_palloc(ngx_pool_t *pool, size_t size); void *ngx_pcalloc(ngx_pool_t *pool, size_t size); ngx_int_t ngx_pfree(ngx_pool_t *pool, void *p); +void *ngx_shalloc(size_t size); +void *ngx_shcalloc(size_t size); +void ngx_shfree(void *p); + ngx_pool_cleanup_t *ngx_pool_cleanup_add(ngx_pool_t *p, size_t size); void ngx_pool_cleanup_file(void *data); diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c index 672eac2ba..f3b19a790 100644 --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -414,11 +414,12 @@ static ngx_int_t ngx_event_module_init(ngx_cycle_t *cycle) { void ***cf; + u_char *shared; + size_t size; ngx_event_conf_t *ecf; ngx_core_conf_t *ccf; + ngx_shm_t shm; #if !(NGX_WIN32) - char *shared; - size_t size; ngx_int_t limit; struct rlimit rlmt; #endif @@ -461,6 +462,8 @@ ngx_event_module_init(ngx_cycle_t *cycle) } } +#endif /* !(NGX_WIN32) */ + if (ccf->master == 0 || ngx_accept_mutex_ptr) { return NGX_OK; @@ -483,11 +486,15 @@ ngx_event_module_init(ngx_cycle_t *cycle) #endif - shared = ngx_create_shared_memory(size, cycle->log); - if (shared == NULL) { + shm.size = size; + shm.log = cycle->log; + + if (ngx_shm_alloc(&shm) != NGX_OK) { return NGX_ERROR; } + shared = shm.addr; + ngx_accept_mutex_ptr = (ngx_atomic_t *) shared; ngx_connection_counter = (ngx_atomic_t *) (shared + 1 * 128); @@ -508,8 +515,6 @@ ngx_event_module_init(ngx_cycle_t *cycle) "counter: %p, %d", ngx_connection_counter, *ngx_connection_counter); -#endif /* !(NGX_WIN32) */ - return NGX_OK; } diff --git a/src/event/ngx_event_busy_lock.c b/src/event/ngx_event_busy_lock.c index 1b09ad96c..2d0bad571 100644 --- a/src/event/ngx_event_busy_lock.c +++ b/src/event/ngx_event_busy_lock.c @@ -20,7 +20,6 @@ static void ngx_event_busy_lock_posted_handler(ngx_event_t *ev); * NGX_AGAIN: the all busy locks are held but we will wait the specified time * NGX_BUSY: ctx->timer == 0: there are many the busy locks * ctx->timer != 0: there are many the waiting locks - * NGX_ERROR: an error occured while the mutex locking */ ngx_int_t @@ -36,6 +35,7 @@ ngx_event_busy_lock(ngx_event_busy_lock_t *bl, ngx_event_busy_lock_ctx_t *ctx) if (bl->busy < bl->max_busy) { bl->busy++; + rc = NGX_OK; } else if (ctx->timer && bl->waiting < bl->max_waiting) { diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c index f63e28872..c85f587f6 100644 --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -1255,7 +1255,7 @@ ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r, ngx_table_elt_t *h, } for (i = 0; i < plcf->redirects->nelts; i++) { - rc = pr->handler(r, h, prefix, pr); + rc = pr[i].handler(r, h, prefix, &pr[i]); if (rc != NGX_DECLINED) { return rc; diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index a73448b99..2784921f2 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -1880,24 +1880,29 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) ls->conf.sndbuf = -1; } - if (conf->server_names.nelts == 0) { - sn = ngx_array_push(&conf->server_names); - if (sn == NULL) { + if (conf->server_name.data == NULL) { + conf->server_name.data = ngx_palloc(cf->pool, NGX_MAXHOSTNAMELEN); + if (conf->server_name.data == NULL) { return NGX_CONF_ERROR; } - sn->name.data = ngx_palloc(cf->pool, NGX_MAXHOSTNAMELEN); - if (sn->name.data == NULL) { - return NGX_CONF_ERROR; - } - - if (gethostname((char *) sn->name.data, NGX_MAXHOSTNAMELEN) == -1) { + if (gethostname((char *) conf->server_name.data, NGX_MAXHOSTNAMELEN) + == -1) + { ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno, "gethostname() failed"); return NGX_CONF_ERROR; } - sn->name.len = ngx_strlen(sn->name.data); + conf->server_name.len = ngx_strlen(conf->server_name.data); + + sn = ngx_array_push(&conf->server_names); + if (sn == NULL) { + return NGX_CONF_ERROR; + } + + sn->name.len = conf->server_name.len; + sn->name.data = conf->server_name.data; sn->core_srv_conf = conf; } diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c index 7fddde087..9ef5a8014 100644 --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -1518,6 +1518,8 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc) clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); if (clcf->post_action.data) { + r->http_version = NGX_HTTP_VERSION_9; + r->header_only = 1; ngx_http_internal_redirect(r, &clcf->post_action, NULL); return; } diff --git a/src/os/unix/ngx_readv_chain.c b/src/os/unix/ngx_readv_chain.c index b55e2f27e..5c2bb5af8 100644 --- a/src/os/unix/ngx_readv_chain.c +++ b/src/os/unix/ngx_readv_chain.c @@ -111,6 +111,21 @@ ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *chain) } } + if (n == 0) { + + /* + * on FreeBSD recv() may return 0 on closed socket + * even if kqueue reported about available data + */ + + ngx_log_error(NGX_LOG_ALERT, c->log, 0, + "recv() returned 0 while kevent() reported " + "%d available bytes", rev->available); + + rev->eof = 1; + rev->available = 0; + } + return n; } diff --git a/src/os/unix/ngx_recv.c b/src/os/unix/ngx_recv.c index 0d3872969..a8a351a80 100644 --- a/src/os/unix/ngx_recv.c +++ b/src/os/unix/ngx_recv.c @@ -70,6 +70,21 @@ ssize_t ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size) } } + if (n == 0) { + + /* + * on FreeBSD recv() may return 0 on closed socket + * even if kqueue reported about available data + */ + + ngx_log_error(NGX_LOG_ALERT, c->log, 0, + "recv() returned 0 while keevnt() reported " + "%d available bytes", rev->available); + + rev->eof = 1; + rev->available = 0; + } + return n; } diff --git a/src/os/unix/ngx_shared.c b/src/os/unix/ngx_shared.c deleted file mode 100644 index 80b5f601f..000000000 --- a/src/os/unix/ngx_shared.c +++ /dev/null @@ -1,95 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - */ - - -#include -#include - - -#if (NGX_HAVE_MAP_ANON) - -void *ngx_create_shared_memory(size_t size, ngx_log_t *log) -{ - void *p; - - p = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0); - - if (p == MAP_FAILED) { - ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, - "mmap(MAP_ANON|MAP_SHARED, %uz) failed", size); - return NULL; - } - - return p; -} - -#elif (NGX_HAVE_MAP_DEVZERO) - -void *ngx_create_shared_memory(size_t size, ngx_log_t *log) -{ - void *p; - ngx_fd_t fd; - - fd = open("/dev/zero", O_RDWR); - - if (fd == -1) { - ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, - "open(\"/dev/zero\") failed"); - return NULL; - } - - p = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); - - if (p == MAP_FAILED) { - ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, - "mmap(/dev/zero, MAP_SHARED, %uz) failed", size); - p = NULL; - } - - if (close(fd) == -1) { - ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, - "close(\"/dev/zero\") failed"); - } - - return p; -} - -#elif (NGX_HAVE_SYSVSHM) - -#include -#include - - -void *ngx_create_shared_memory(size_t size, ngx_log_t *log) -{ - int id; - void *p; - - id = shmget(IPC_PRIVATE, size, (SHM_R|SHM_W|IPC_CREAT)); - - if (id == -1) { - ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, - "shmget(%uz) failed", size); - return NULL; - } - - ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "shmget id: %d", id); - - p = shmat(id, NULL, 0); - - if (p == (void *) -1) { - ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "shmat() failed"); - p = NULL; - } - - if (shmctl(id, IPC_RMID, NULL) == -1) { - ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "shmctl(IPC_RMID) failed"); - p = NULL; - } - - return p; -} - -#endif diff --git a/src/os/unix/ngx_shmem.c b/src/os/unix/ngx_shmem.c new file mode 100644 index 000000000..66df1bbe4 --- /dev/null +++ b/src/os/unix/ngx_shmem.c @@ -0,0 +1,123 @@ + +/* + * Copyright (C) Igor Sysoev + */ + + +#include +#include + + +#if (NGX_HAVE_MAP_ANON) + +ngx_int_t +ngx_shm_alloc(ngx_shm_t *shm) +{ + shm->addr = mmap(NULL, shm->size, + PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0); + + if (shm->addr == MAP_FAILED) { + ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, + "mmap(MAP_ANON|MAP_SHARED, %uz) failed", shm->size); + return NGX_ERROR; + } + + return NGX_OK; +} + + +void +ngx_shm_free(ngx_shm_t *shm) +{ + if (munmap(shm->addr, shm->size) == -1) { + ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, + "munmap(%p, %uz) failed", shm->addr, shm->size); + } +} + +#elif (NGX_HAVE_MAP_DEVZERO) + +ngx_int_t +ngx_shm_alloc(ngx_shm_t *shm) +{ + ngx_fd_t fd; + + fd = open("/dev/zero", O_RDWR); + + if (fd == -1) { + ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, + "open(\"/dev/zero\") failed"); + return NGX_ERROR; + } + + shm->addr = mmap(NULL, shm->size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + + if (shm->addr == MAP_FAILED) { + ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, + "mmap(/dev/zero, MAP_SHARED, %uz) failed", shm->size); + } + + if (close(fd) == -1) { + ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, + "close(\"/dev/zero\") failed"); + } + + return (shm->addr == MAP_FAILED) ? NGX_ERROR : NGX_OK; +} + + +void +ngx_shm_free(ngx_shm_t *shm) +{ + if (munmap(shm->addr, shm->size) == -1) { + ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, + "munmap(%p, %uz) failed", shm->addr, shm->size); + } +} + +#elif (NGX_HAVE_SYSVSHM) + +#include +#include + + +ngx_int_t +ngx_shm_alloc(ngx_shm_t *shm) +{ + int id; + + id = shmget(IPC_PRIVATE, shm->size, (SHM_R|SHM_W|IPC_CREAT)); + + if (id == -1) { + ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, + "shmget(%uz) failed", shm->size); + return NGX_ERROR; + } + + ngx_log_debug1(NGX_LOG_DEBUG_CORE, shm->log, 0, "shmget id: %d", id); + + shm->addr = shmat(id, NULL, 0); + + if (shm->addr == (void *) -1) { + ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, "shmat() failed"); + } + + if (shmctl(id, IPC_RMID, NULL) == -1) { + ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, + "shmctl(IPC_RMID) failed"); + } + + return (shm->addr == (void *) -1) ? NGX_ERROR : NGX_OK; +} + + +void +ngx_shm_free(ngx_shm_t *shm) +{ + if (shmdt(shm->addr) == -1) { + ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, + "shmdt(%p) failed", shm->addr); + } +} + +#endif diff --git a/src/os/unix/ngx_shared.h b/src/os/unix/ngx_shmem.h similarity index 52% rename from src/os/unix/ngx_shared.h rename to src/os/unix/ngx_shmem.h index 29e4a33d5..72c54f166 100644 --- a/src/os/unix/ngx_shared.h +++ b/src/os/unix/ngx_shmem.h @@ -12,7 +12,15 @@ #include -void *ngx_create_shared_memory(size_t size, ngx_log_t *log); +typedef struct { + u_char *addr; + size_t size; + ngx_log_t *log; +} ngx_shm_t; + + +ngx_int_t ngx_shm_alloc(ngx_shm_t *shm); +void ngx_shm_free(ngx_shm_t *shm); #endif /* _NGX_SHARED_H_INCLUDED_ */ diff --git a/src/os/win32/ngx_shared.h b/src/os/win32/ngx_shared.h deleted file mode 100644 index 29e4a33d5..000000000 --- a/src/os/win32/ngx_shared.h +++ /dev/null @@ -1,18 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - */ - - -#ifndef _NGX_SHARED_H_INCLUDED_ -#define _NGX_SHARED_H_INCLUDED_ - - -#include -#include - - -void *ngx_create_shared_memory(size_t size, ngx_log_t *log); - - -#endif /* _NGX_SHARED_H_INCLUDED_ */ diff --git a/src/os/win32/ngx_shmem.c b/src/os/win32/ngx_shmem.c new file mode 100644 index 000000000..5c8fb6223 --- /dev/null +++ b/src/os/win32/ngx_shmem.c @@ -0,0 +1,58 @@ + +/* + * Copyright (C) Igor Sysoev + */ + + +#include +#include + + +/* + * TODO: + * maping name or inheritable handle + */ + +ngx_int_t +ngx_shm_alloc(ngx_shm_t *shm) +{ + shm->handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, + 0, shm->size, NULL); + + if (shm->handle == NULL) { + ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, + "CreateFileMapping(%uz) failed", shm->size); + return NGX_ERROR; + } + + shm->addr = MapViewOfFile(shm->handle, FILE_MAP_WRITE, 0, 0, 0); + + if (shm->addr == NULL) { + ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, + "MapViewOfFile(%uz) failed", shm->size); + + if (CloseHandle(shm->handle) == 0) { + ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, + "CloseHandle() failed"); + } + + return NGX_ERROR; + } + + return NGX_OK; +} + + +void +ngx_shm_free(ngx_shm_t *shm) +{ + if (UnmapViewOfFile(shm->addr) == 0) { + ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, + "UnmapViewOfFile(%p) failed", shm->addr); + } + + if (CloseHandle(shm->handle) == 0) { + ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, + "CloseHandle() failed"); + } +} diff --git a/src/os/win32/ngx_shmem.h b/src/os/win32/ngx_shmem.h new file mode 100644 index 000000000..fe3e71df6 --- /dev/null +++ b/src/os/win32/ngx_shmem.h @@ -0,0 +1,27 @@ + +/* + * Copyright (C) Igor Sysoev + */ + + +#ifndef _NGX_SHARED_H_INCLUDED_ +#define _NGX_SHARED_H_INCLUDED_ + + +#include +#include + + +typedef struct { + u_char *addr; + size_t size; + HANDLE handle; + ngx_log_t *log; +} ngx_shm_t; + + +ngx_int_t ngx_shm_alloc(ngx_shm_t *shm); +void ngx_shm_free(ngx_shm_t *shm); + + +#endif /* _NGX_SHARED_H_INCLUDED_ */