diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/nginx.h | 2 | ||||
-rw-r--r-- | src/core/ngx_open_file_cache.c | 494 | ||||
-rw-r--r-- | src/core/ngx_open_file_cache.h | 15 | ||||
-rw-r--r-- | src/core/ngx_queue.h | 2 | ||||
-rw-r--r-- | src/core/ngx_rbtree.c | 12 | ||||
-rw-r--r-- | src/core/ngx_regex.c | 33 | ||||
-rw-r--r-- | src/core/ngx_regex.h | 8 | ||||
-rw-r--r-- | src/core/ngx_resolver.c | 27 | ||||
-rw-r--r-- | src/core/ngx_slab.c | 15 | ||||
-rw-r--r-- | src/core/ngx_string.c | 19 |
10 files changed, 382 insertions, 245 deletions
diff --git a/src/core/nginx.h b/src/core/nginx.h index bae7d8339..3dac5c798 100644 --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -8,7 +8,7 @@ #define _NGINX_H_INCLUDED_ -#define NGINX_VERSION "0.6.22" +#define NGINX_VERSION "0.6.23" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" diff --git a/src/core/ngx_open_file_cache.c b/src/core/ngx_open_file_cache.c index d518f4b96..9c5cc6732 100644 --- a/src/core/ngx_open_file_cache.c +++ b/src/core/ngx_open_file_cache.c @@ -18,22 +18,27 @@ static void ngx_open_file_cache_cleanup(void *data); -static void ngx_open_file_cleanup(void *data); -static void ngx_close_cached_file(ngx_open_file_cache_t *cache, - ngx_cached_open_file_t *file, ngx_log_t *log); static ngx_int_t ngx_open_and_stat_file(u_char *name, ngx_open_file_info_t *of, ngx_log_t *log); +static void ngx_open_file_add_event(ngx_open_file_cache_t *cache, + ngx_cached_open_file_t *file, ngx_open_file_info_t *of, ngx_log_t *log); +static void ngx_open_file_cleanup(void *data); +static void ngx_close_cached_file(ngx_open_file_cache_t *cache, + ngx_cached_open_file_t *file, ngx_uint_t min_uses, ngx_log_t *log); +static void ngx_open_file_del_event(ngx_cached_open_file_t *file); static void ngx_expire_old_cached_files(ngx_open_file_cache_t *cache, ngx_uint_t n, ngx_log_t *log); static void ngx_open_file_cache_rbtree_insert_value(ngx_rbtree_node_t *temp, ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel); +static ngx_cached_open_file_t * + ngx_open_file_lookup(ngx_open_file_cache_t *cache, ngx_str_t *name, + uint32_t hash); static void ngx_open_file_cache_remove(ngx_event_t *ev); ngx_open_file_cache_t * ngx_open_file_cache_init(ngx_pool_t *pool, ngx_uint_t max, time_t inactive) { - ngx_rbtree_node_t *sentinel; ngx_pool_cleanup_t *cln; ngx_open_file_cache_t *cache; @@ -42,20 +47,11 @@ ngx_open_file_cache_init(ngx_pool_t *pool, ngx_uint_t max, time_t inactive) return NULL; } - cache->list_head.prev = NULL; - cache->list_head.next = &cache->list_tail; - - cache->list_tail.prev = &cache->list_head; - cache->list_tail.next = NULL; - - sentinel = ngx_palloc(pool, sizeof(ngx_rbtree_node_t)); - if (sentinel == NULL) { - return NULL; - } - - ngx_rbtree_init(&cache->rbtree, sentinel, + ngx_rbtree_init(&cache->rbtree, &cache->sentinel, ngx_open_file_cache_rbtree_insert_value); + ngx_queue_init(&cache->expire_queue); + cache->current = 0; cache->max = max; cache->inactive = inactive; @@ -77,6 +73,7 @@ ngx_open_file_cache_cleanup(void *data) { ngx_open_file_cache_t *cache = data; + ngx_queue_t *q; ngx_cached_open_file_t *file; ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, @@ -84,14 +81,15 @@ ngx_open_file_cache_cleanup(void *data) for ( ;; ) { - file = cache->list_tail.prev; - - if (file == &cache->list_head) { + if (ngx_queue_empty(&cache->expire_queue)) { break; } - file->next->prev = file->prev; - file->prev->next = file->next; + q = ngx_queue_last(&cache->expire_queue); + + file = ngx_queue_data(q, ngx_cached_open_file_t, queue); + + ngx_queue_remove(q); ngx_rbtree_delete(&cache->rbtree, &file->node); @@ -103,7 +101,7 @@ ngx_open_file_cache_cleanup(void *data) if (!file->err && !file->is_dir) { file->close = 1; file->count = 0; - ngx_close_cached_file(cache, file, ngx_cycle->log); + ngx_close_cached_file(cache, file, 0, ngx_cycle->log); } else { ngx_free(file->name); @@ -132,11 +130,9 @@ ngx_open_cached_file(ngx_open_file_cache_t *cache, ngx_str_t *name, time_t now; uint32_t hash; ngx_int_t rc; - ngx_rbtree_node_t *node, *sentinel; ngx_pool_cleanup_t *cln; ngx_cached_open_file_t *file; ngx_pool_cleanup_file_t *clnf; - ngx_open_file_cache_event_t *fev; ngx_open_file_cache_cleanup_t *ofcln; of->err = 0; @@ -167,145 +163,147 @@ ngx_open_cached_file(ngx_open_file_cache_t *cache, ngx_str_t *name, return NGX_ERROR; } + now = ngx_time(); + hash = ngx_crc32_long(name->data, name->len); - node = cache->rbtree.root; - sentinel = cache->rbtree.sentinel; + file = ngx_open_file_lookup(cache, name, hash); - now = ngx_time(); + if (file) { - while (node != sentinel) { + file->uses++; - if (hash < node->key) { - node = node->left; - continue; - } + ngx_queue_remove(&file->queue); - if (hash > node->key) { - node = node->right; - continue; - } + if (file->fd == NGX_INVALID_FILE && file->err == 0 && !file->is_dir) { - /* hash == node->key */ + /* file was not used often enough to keep open */ - do { - file = (ngx_cached_open_file_t *) node; + rc = ngx_open_and_stat_file(name->data, of, pool->log); - rc = ngx_strcmp(name->data, file->name); + if (rc != NGX_OK && (of->err == 0 || !of->errors)) { + goto failed; + } - if (rc == 0) { + goto add_event; + } - file->next->prev = file->prev; - file->prev->next = file->next; + if ((file->event && file->use_event) + || (file->event == NULL && now - file->created < of->valid)) + { + if (file->err == 0) { - if (file->event || now - file->created < of->retest) { - if (file->err == 0) { - of->fd = file->fd; - of->uniq = file->uniq; - of->mtime = file->mtime; - of->size = file->size; + of->fd = file->fd; + of->uniq = file->uniq; + of->mtime = file->mtime; + of->size = file->size; - of->is_dir = file->is_dir; - of->is_file = file->is_file; - of->is_link = file->is_link; - of->is_exec = file->is_exec; + of->is_dir = file->is_dir; + of->is_file = file->is_file; + of->is_link = file->is_link; + of->is_exec = file->is_exec; - if (!file->is_dir) { - file->count++; - } + if (!file->is_dir) { + file->count++; + ngx_open_file_add_event(cache, file, of, pool->log); + } - } else { - of->err = file->err; - } + } else { + of->err = file->err; + } - goto found; - } + goto found; + } - ngx_log_debug4(NGX_LOG_DEBUG_CORE, pool->log, 0, - "retest open file: %s, fd:%d, c:%d, e:%d", - file->name, file->fd, file->count, file->err); + ngx_log_debug4(NGX_LOG_DEBUG_CORE, pool->log, 0, + "retest open file: %s, fd:%d, c:%d, e:%d", + file->name, file->fd, file->count, file->err); - if (file->is_dir) { + if (file->is_dir) { - /* - * chances that directory became file are very small - * so test_dir flag allows to use a single ngx_file_info() - * syscall instead of three syscalls - */ + /* + * chances that directory became file are very small + * so test_dir flag allows to use a single syscall + * in ngx_file_info() instead of three syscalls + */ - of->test_dir = 1; - } + of->test_dir = 1; + } - rc = ngx_open_and_stat_file(name->data, of, pool->log); + rc = ngx_open_and_stat_file(name->data, of, pool->log); - if (rc != NGX_OK && (of->err == 0 || !of->errors)) { - goto failed; - } + if (rc != NGX_OK && (of->err == 0 || !of->errors)) { + goto failed; + } - if (of->is_dir) { - if (file->is_dir || file->err) { - goto update; - } + if (of->is_dir) { - /* file became directory */ + if (file->is_dir || file->err) { + goto update; + } - } else if (of->err == 0) { /* file */ + /* file became directory */ - if (file->is_dir || file->err) { - goto update; - } + } else if (of->err == 0) { /* file */ - if (of->uniq == file->uniq - && of->mtime == file->mtime - && of->size == file->size) - { - if (ngx_close_file(of->fd) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_ALERT, pool->log, ngx_errno, - ngx_close_file_n " \"%s\" failed", - name->data); - } + if (file->is_dir || file->err) { + goto add_event; + } - of->fd = file->fd; - file->count++; + if (of->uniq == file->uniq + && of->mtime == file->mtime + && of->size == file->size) + { + if (ngx_close_file(of->fd) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_ALERT, pool->log, ngx_errno, + ngx_close_file_n " \"%s\" failed", + name->data); + } - goto renew; - } + of->fd = file->fd; + file->count++; - /* file was changed */ + if (file->event) { + file->use_event = 1; + goto renew; + } - } else { /* error to cache */ + ngx_open_file_add_event(cache, file, of, pool->log); - if (file->err || file->is_dir) { - goto update; - } + goto renew; + } - /* file was removed, etc. */ - } + /* file was changed */ - if (file->count == 0) { - if (ngx_close_file(file->fd) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_ALERT, pool->log, ngx_errno, - ngx_close_file_n " \"%s\" failed", - name->data); - } + } else { /* error to cache */ - goto update; - } + if (file->err || file->is_dir) { + goto update; + } - ngx_rbtree_delete(&cache->rbtree, &file->node); + /* file was removed, etc. */ + } - cache->current--; + if (file->count == 0) { - file->close = 1; + ngx_open_file_del_event(file); - goto create; + if (ngx_close_file(file->fd) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_ALERT, pool->log, ngx_errno, + ngx_close_file_n " \"%s\" failed", + name->data); } - node = (rc < 0) ? node->left : node->right; + goto add_event; + } - } while (node != sentinel && hash == node->key); + ngx_rbtree_delete(&cache->rbtree, &file->node); - break; + cache->current--; + + file->close = 1; + + goto create; } /* not found */ @@ -346,50 +344,16 @@ create: cache->current++; + file->uses = 1; file->count = 0; + file->use_event = 0; + file->event = NULL; -update: - - if (of->events - && (ngx_event_flags & NGX_USE_VNODE_EVENT) - && of->fd != NGX_INVALID_FILE) - { - file->event = ngx_calloc(sizeof(ngx_event_t), pool->log); - if (file->event== NULL) { - goto failed; - } - - fev = ngx_alloc(sizeof(ngx_open_file_cache_event_t), pool->log); - if (fev == NULL) { - goto failed; - } - - fev->fd = of->fd; - fev->file = file; - fev->cache = cache; - - file->event->handler = ngx_open_file_cache_remove; - file->event->data = fev; - - /* - * although vnode event may be called while ngx_cycle->poll - * destruction; however, cleanup procedures are run before any - * memory freeing and events will be canceled. - */ - - file->event->log = ngx_cycle->log; +add_event: - if (ngx_add_event(file->event, NGX_VNODE_EVENT, NGX_ONESHOT_EVENT) - != NGX_OK) - { - ngx_free(file->event->data); - ngx_free(file->event); - goto failed; - } + ngx_open_file_add_event(cache, file, of, pool->log); - } else { - file->event = NULL; - } +update: file->fd = of->fd; file->err = of->err; @@ -419,16 +383,11 @@ found: file->accessed = now; - /* add to the inactive list head */ - - file->next = cache->list_head.next; - file->next->prev = file; - file->prev = &cache->list_head; - cache->list_head.next = file; + ngx_queue_insert_head(&cache->expire_queue, &file->queue); - ngx_log_debug4(NGX_LOG_DEBUG_CORE, pool->log, 0, - "cached open file: %s, fd:%d, c:%d, e:%d", - file->name, file->fd, file->count, file->err); + ngx_log_debug5(NGX_LOG_DEBUG_CORE, pool->log, 0, + "cached open file: %s, fd:%d, c:%d, e:%d, u:%d", + file->name, file->fd, file->count, file->err, file->uses); if (of->err == 0) { @@ -438,6 +397,7 @@ found: ofcln->cache = cache; ofcln->file = file; + ofcln->min_uses = of->min_uses; ofcln->log = pool->log; } @@ -543,6 +503,72 @@ ngx_open_and_stat_file(u_char *name, ngx_open_file_info_t *of, ngx_log_t *log) } +/* + * we ignore any possible event setting error and + * fallback to usual periodic file retests + */ + +static void +ngx_open_file_add_event(ngx_open_file_cache_t *cache, + ngx_cached_open_file_t *file, ngx_open_file_info_t *of, ngx_log_t *log) +{ + ngx_open_file_cache_event_t *fev; + + if (!(ngx_event_flags & NGX_USE_VNODE_EVENT) + || !of->events + || file->event + || of->fd == NGX_INVALID_FILE + || file->uses < of->min_uses) + { + return; + } + + file->event = ngx_calloc(sizeof(ngx_event_t), log); + if (file->event== NULL) { + return; + } + + fev = ngx_alloc(sizeof(ngx_open_file_cache_event_t), log); + if (fev == NULL) { + ngx_free(file->event); + file->event = NULL; + return; + } + + fev->fd = of->fd; + fev->file = file; + fev->cache = cache; + + file->event->handler = ngx_open_file_cache_remove; + file->event->data = fev; + + /* + * although vnode event may be called while ngx_cycle->poll + * destruction, however, cleanup procedures are run before any + * memory freeing and events will be canceled. + */ + + file->event->log = ngx_cycle->log; + + if (ngx_add_event(file->event, NGX_VNODE_EVENT, NGX_ONESHOT_EVENT) + != NGX_OK) + { + ngx_free(file->event->data); + ngx_free(file->event); + file->event = NULL; + return; + } + + /* + * we do not file->use_event here because there may be a race + * condition between opening file and adding event, so we rely + * upon event notification only after first file revalidation + */ + + return; +} + + static void ngx_open_file_cleanup(void *data) { @@ -550,7 +576,7 @@ ngx_open_file_cleanup(void *data) c->file->count--; - ngx_close_cached_file(c->cache, c->file, c->log); + ngx_close_cached_file(c->cache, c->file, c->min_uses, c->log); /* drop one or two expired open files */ ngx_expire_old_cached_files(c->cache, 1, c->log); @@ -559,50 +585,43 @@ ngx_open_file_cleanup(void *data) static void ngx_close_cached_file(ngx_open_file_cache_t *cache, - ngx_cached_open_file_t *file, ngx_log_t *log) + ngx_cached_open_file_t *file, ngx_uint_t min_uses, ngx_log_t *log) { - ngx_log_debug4(NGX_LOG_DEBUG_CORE, log, 0, - "close cached open file: %s, fd:%d, c:%d, %d", - file->name, file->fd, file->count, file->close); + ngx_log_debug5(NGX_LOG_DEBUG_CORE, log, 0, + "close cached open file: %s, fd:%d, c:%d, u:%d, %d", + file->name, file->fd, file->count, file->uses, file->close); if (!file->close) { file->accessed = ngx_time(); - if (cache->list_head.next != file) { - - /* delete from inactive list */ + ngx_queue_remove(&file->queue); - file->next->prev = file->prev; - file->prev->next = file->next; + ngx_queue_insert_head(&cache->expire_queue, &file->queue); - /* add to the inactive list head */ - - file->next = cache->list_head.next; - file->next->prev = file; - file->prev = &cache->list_head; - cache->list_head.next = file; + if (file->uses >= min_uses || file->count) { + return; } + } + ngx_open_file_del_event(file); + + if (file->count) { return; } - if (file->event) { - (void) ngx_del_event(file->event, NGX_VNODE_EVENT, - file->count ? NGX_FLUSH_EVENT : NGX_CLOSE_EVENT); + if (file->fd != NGX_INVALID_FILE) { - ngx_free(file->event->data); - ngx_free(file->event); - file->event = NULL; - } + if (ngx_close_file(file->fd) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, + ngx_close_file_n " \"%s\" failed", file->name); + } - if (file->count) { - return; + file->fd = NGX_INVALID_FILE; } - if (ngx_close_file(file->fd) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, - ngx_close_file_n " \"%s\" failed", file->name); + if (!file->close) { + return; } ngx_free(file->name); @@ -611,10 +630,28 @@ ngx_close_cached_file(ngx_open_file_cache_t *cache, static void +ngx_open_file_del_event(ngx_cached_open_file_t *file) +{ + if (file->event == NULL) { + return; + } + + (void) ngx_del_event(file->event, NGX_VNODE_EVENT, + file->count ? NGX_FLUSH_EVENT : NGX_CLOSE_EVENT); + + ngx_free(file->event->data); + ngx_free(file->event); + file->event = NULL; + file->use_event = 0; +} + + +static void ngx_expire_old_cached_files(ngx_open_file_cache_t *cache, ngx_uint_t n, ngx_log_t *log) { time_t now; + ngx_queue_t *q; ngx_cached_open_file_t *file; now = ngx_time(); @@ -627,18 +664,19 @@ ngx_expire_old_cached_files(ngx_open_file_cache_t *cache, ngx_uint_t n, while (n < 3) { - file = cache->list_tail.prev; - - if (file == &cache->list_head) { + if (ngx_queue_empty(&cache->expire_queue)) { return; } + q = ngx_queue_last(&cache->expire_queue); + + file = ngx_queue_data(q, ngx_cached_open_file_t, queue); + if (n++ != 0 && now - file->accessed <= cache->inactive) { return; } - file->next->prev = file->prev; - file->prev->next = file->next; + ngx_queue_remove(q); ngx_rbtree_delete(&cache->rbtree, &file->node); @@ -649,7 +687,7 @@ ngx_expire_old_cached_files(ngx_open_file_cache_t *cache, ngx_uint_t n, if (!file->err && !file->is_dir) { file->close = 1; - ngx_close_cached_file(cache, file, log); + ngx_close_cached_file(cache, file, 0, log); } else { ngx_free(file->name); @@ -700,6 +738,51 @@ ngx_open_file_cache_rbtree_insert_value(ngx_rbtree_node_t *temp, } +static ngx_cached_open_file_t * +ngx_open_file_lookup(ngx_open_file_cache_t *cache, ngx_str_t *name, + uint32_t hash) +{ + ngx_int_t rc; + ngx_rbtree_node_t *node, *sentinel; + ngx_cached_open_file_t *file; + + node = cache->rbtree.root; + sentinel = cache->rbtree.sentinel; + + while (node != sentinel) { + + if (hash < node->key) { + node = node->left; + continue; + } + + if (hash > node->key) { + node = node->right; + continue; + } + + /* hash == node->key */ + + do { + file = (ngx_cached_open_file_t *) node; + + rc = ngx_strcmp(name->data, file->name); + + if (rc == 0) { + return file; + } + + node = (rc < 0) ? node->left : node->right; + + } while (node != sentinel && hash == node->key); + + break; + } + + return NULL; +} + + static void ngx_open_file_cache_remove(ngx_event_t *ev) { @@ -709,8 +792,7 @@ ngx_open_file_cache_remove(ngx_event_t *ev) fev = ev->data; file = fev->file; - file->next->prev = file->prev; - file->prev->next = file->next; + ngx_queue_remove(&file->queue); ngx_rbtree_delete(&fev->cache->rbtree, &file->node); @@ -721,7 +803,7 @@ ngx_open_file_cache_remove(ngx_event_t *ev) file->close = 1; - ngx_close_cached_file(fev->cache, file, ev->log); + ngx_close_cached_file(fev->cache, file, 0, ev->log); /* free memory only when fev->cache and fev->file are already not needed */ diff --git a/src/core/ngx_open_file_cache.h b/src/core/ngx_open_file_cache.h index cc0d899a2..dd294e77a 100644 --- a/src/core/ngx_open_file_cache.h +++ b/src/core/ngx_open_file_cache.h @@ -19,7 +19,9 @@ typedef struct { off_t size; ngx_err_t err; - time_t retest; + time_t valid; + + ngx_uint_t min_uses; unsigned test_dir:1; unsigned errors:1; @@ -36,8 +38,7 @@ typedef struct ngx_cached_open_file_s ngx_cached_open_file_t; struct ngx_cached_open_file_s { ngx_rbtree_node_t node; - ngx_cached_open_file_t *prev; - ngx_cached_open_file_t *next; + ngx_queue_t queue; u_char *name; time_t created; @@ -49,8 +50,11 @@ struct ngx_cached_open_file_s { off_t size; ngx_err_t err; + uint32_t uses; + unsigned count:24; unsigned close:1; + unsigned use_event:1; unsigned is_dir:1; unsigned is_file:1; @@ -63,8 +67,8 @@ struct ngx_cached_open_file_s { typedef struct { ngx_rbtree_t rbtree; - ngx_cached_open_file_t list_head; - ngx_cached_open_file_t list_tail; + ngx_rbtree_node_t sentinel; + ngx_queue_t expire_queue; ngx_uint_t current; ngx_uint_t max; @@ -75,6 +79,7 @@ typedef struct { typedef struct { ngx_open_file_cache_t *cache; ngx_cached_open_file_t *file; + ngx_uint_t min_uses; ngx_log_t *log; } ngx_open_file_cache_cleanup_t; diff --git a/src/core/ngx_queue.h b/src/core/ngx_queue.h index 39296add4..1407d85a6 100644 --- a/src/core/ngx_queue.h +++ b/src/core/ngx_queue.h @@ -22,7 +22,7 @@ struct ngx_queue_s { #define ngx_queue_init(q) \ (q)->prev = q; \ - (q)->next = q; + (q)->next = q #define ngx_queue_empty(h) \ diff --git a/src/core/ngx_rbtree.c b/src/core/ngx_rbtree.c index 7d240fe81..749b601f2 100644 --- a/src/core/ngx_rbtree.c +++ b/src/core/ngx_rbtree.c @@ -242,14 +242,14 @@ ngx_rbtree_delete(ngx_thread_volatile ngx_rbtree_t *tree, if (subst->right != sentinel) { subst->right->parent = subst; } - - /* DEBUG stuff */ - node->left = NULL; - node->right = NULL; - node->parent = NULL; - node->key = 0; } + /* DEBUG stuff */ + node->left = NULL; + node->right = NULL; + node->parent = NULL; + node->key = 0; + if (red) { return; } diff --git a/src/core/ngx_regex.c b/src/core/ngx_regex.c index eda243bec..be2dae79b 100644 --- a/src/core/ngx_regex.c +++ b/src/core/ngx_regex.c @@ -114,6 +114,39 @@ ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s, int *captures, ngx_int_t size) } +ngx_int_t +ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log) +{ + ngx_int_t n; + ngx_uint_t i; + ngx_regex_elt_t *re; + + re = a->elts; + + for (i = 0; i < a->nelts; i++) { + + n = ngx_regex_exec(re[i].regex, s, NULL, 0); + + if (n == NGX_REGEX_NO_MATCHED) { + continue; + } + + if (n < 0) { + ngx_log_error(NGX_LOG_ALERT, log, 0, + ngx_regex_exec_n " failed: %d on \"%V\" using \"%s\"", + n, s, re[i].name); + return NGX_ERROR; + } + + /* match */ + + return NGX_OK; + } + + return NGX_DECLINED; +} + + static void * ngx_libc_cdecl ngx_regex_malloc(size_t size) { diff --git a/src/core/ngx_regex.h b/src/core/ngx_regex.h index 430637721..e31470f9f 100644 --- a/src/core/ngx_regex.h +++ b/src/core/ngx_regex.h @@ -20,12 +20,20 @@ typedef pcre ngx_regex_t; +typedef struct { + ngx_regex_t *regex; + u_char *name; +} ngx_regex_elt_t; + + void ngx_regex_init(void); ngx_regex_t *ngx_regex_compile(ngx_str_t *pattern, ngx_int_t options, ngx_pool_t *pool, ngx_str_t *err); ngx_int_t ngx_regex_capture_count(ngx_regex_t *re); ngx_int_t ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s, int *captures, ngx_int_t size); +ngx_int_t ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log); + #define ngx_regex_exec_n "pcre_exec()" #define ngx_regex_capture_count_n "pcre_fullinfo()" diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c index be0121e2e..ef2c92ba4 100644 --- a/src/core/ngx_resolver.c +++ b/src/core/ngx_resolver.c @@ -669,17 +669,8 @@ ngx_resolver_expire(ngx_resolver_t *r, ngx_rbtree_t *tree, ngx_queue_t *queue) return; } -#if (NGX_DEBUG) - { - ngx_str_t s; - - s.len = rn->nlen; - s.data = rn->name; - - ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0, - "resolver expire \"%V\"", &s); - } -#endif + ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0, + "resolver expire \"%*s\"", (size_t) rn->nlen, rn->name); ngx_queue_remove(q); @@ -783,17 +774,9 @@ ngx_resolver_resend(ngx_resolver_t *r, ngx_rbtree_t *tree, ngx_queue_t *queue) return rn->expire - now; } -#if (NGX_DEBUG) - { - ngx_str_t s; - - s.len = rn->nlen; - s.data = rn->name; - - ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0, - "resolver resend \"%V\" %p", &s, rn->waiting); - } -#endif + ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0, + "resolver resend \"%*s\" %p", + (size_t) rn->nlen, rn->name, rn->waiting); ngx_queue_remove(q); diff --git a/src/core/ngx_slab.c b/src/core/ngx_slab.c index 9f63a91eb..b187026d8 100644 --- a/src/core/ngx_slab.c +++ b/src/core/ngx_slab.c @@ -58,9 +58,22 @@ #if (NGX_DEBUG_MALLOC) -#define ngx_slab_junk(p, size) ngx_memset(p, 0xD0, size) + +#define ngx_slab_junk(p, size) ngx_memset(p, 0xD0, size) + +#else + +#if (NGX_FREEBSD) + +#define ngx_slab_junk(p, size) \ + if (ngx_freebsd_debug_malloc) ngx_memset(p, 0xD0, size) + #else + #define ngx_slab_junk(p, size) + +#endif + #endif static ngx_slab_page_t *ngx_slab_alloc_pages(ngx_slab_pool_t *pool, diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c index f878c559f..d9a5480da 100644 --- a/src/core/ngx_string.c +++ b/src/core/ngx_string.c @@ -63,6 +63,7 @@ ngx_pstrdup(ngx_pool_t *pool, ngx_str_t *src) * %V ngx_str_t * * %v ngx_variable_value_t * * %s null-terminated string + * %*s length and string * %Z '\0' * %N '\n' * %c char @@ -112,7 +113,7 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args) * but icc issues the warning */ int d; - size_t len; + size_t len, slen; uint32_t ui32; int64_t i64; uint64_t ui64; @@ -146,6 +147,7 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args) sign = 1; hexadecimal = 0; max_width = 0; + slen = 0; p = temp + NGX_INT64_LEN; @@ -179,6 +181,11 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args) fmt++; continue; + case '*': + slen = va_arg(args, u_int); + fmt++; + continue; + default: break; } @@ -214,9 +221,15 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args) case 's': p = va_arg(args, u_char *); - while (*p && buf < last) { - *buf++ = *p++; + if (slen == 0) { + while (*p && buf < last) { + *buf++ = *p++; + } + + } else { + buf = ngx_cpymem(buf, p, slen); } + fmt++; continue; |