Mercurial > hg > nginx-vendor-current
diff src/http/ngx_http_file_cache.c @ 588:b6a5942a4e6a NGINX_0_8_46
nginx 0.8.46
*) Change: now the "proxy_no_cache", "fastcgi_no_cache",
"uwsgi_no_cache", and "scgi_no_cache" directives affect on a cached
response saving only.
*) Feature: the "proxy_cache_bypass", "fastcgi_cache_bypass",
"uwsgi_cache_bypass", and "scgi_cache_bypass" directives.
*) Bugfix: nginx did not free memory in cache keys zones if there was
an error during working with backend: the memory was freed only
after inactivity time or on memory low condition.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 19 Jul 2010 00:00:00 +0400 |
parents | ff463db0be31 |
children | cde3626b2d0d |
line wrap: on
line diff
--- a/src/http/ngx_http_file_cache.c +++ b/src/http/ngx_http_file_cache.c @@ -19,6 +19,8 @@ static void ngx_http_cache_aio_event_han #endif static ngx_int_t ngx_http_file_cache_exists(ngx_http_file_cache_t *cache, ngx_http_cache_t *c); +static ngx_int_t ngx_http_file_cache_name(ngx_http_request_t *r, + ngx_path_t *path); static ngx_http_file_cache_node_t * ngx_http_file_cache_lookup(ngx_http_file_cache_t *cache, u_char *key); static void ngx_http_file_cache_rbtree_insert_value(ngx_rbtree_node_t *temp, @@ -44,6 +46,7 @@ static ngx_int_t ngx_http_file_cache_del ngx_str_t ngx_http_cache_status[] = { ngx_string("MISS"), + ngx_string("BYPASS"), ngx_string("EXPIRED"), ngx_string("STALE"), ngx_string("UPDATING"), @@ -142,6 +145,59 @@ ngx_http_file_cache_init(ngx_shm_zone_t } +ngx_int_t +ngx_http_file_cache_new(ngx_http_request_t *r) +{ + ngx_http_cache_t *c; + + c = ngx_pcalloc(r->pool, sizeof(ngx_http_cache_t)); + if (c == NULL) { + return NGX_ERROR; + } + + if (ngx_array_init(&c->keys, r->pool, 4, sizeof(ngx_str_t)) != NGX_OK) { + return NGX_ERROR; + } + + r->cache = c; + c->file.log = r->connection->log; + + return NGX_OK; +} + + +ngx_int_t +ngx_http_file_cache_create(ngx_http_request_t *r) +{ + ngx_http_cache_t *c; + ngx_pool_cleanup_t *cln; + ngx_http_file_cache_t *cache; + + ngx_http_file_cache_create_key(r); + + c = r->cache; + cache = c->file_cache; + + cln = ngx_pool_cleanup_add(r->pool, 0); + if (cln == NULL) { + return NGX_ERROR; + } + + if (ngx_http_file_cache_exists(cache, c) == NGX_ERROR) { + return NGX_ERROR; + } + + cln->handler = ngx_http_file_cache_cleanup; + cln->data = c; + + if (ngx_http_file_cache_name(r, cache->path) != NGX_OK) { + return NGX_ERROR; + } + + return NGX_OK; +} + + void ngx_http_file_cache_create_key(ngx_http_request_t *r) { @@ -180,10 +236,8 @@ ngx_http_file_cache_create_key(ngx_http_ ngx_int_t ngx_http_file_cache_open(ngx_http_request_t *r) { - u_char *p; ngx_int_t rc, rv; ngx_uint_t cold, test; - ngx_path_t *path; ngx_http_cache_t *c; ngx_pool_cleanup_t *cln; ngx_open_file_info_t of; @@ -249,27 +303,10 @@ ngx_http_file_cache_open(ngx_http_reques } } - path = cache->path; - - c->file.name.len = path->name.len + 1 + path->len - + 2 * NGX_HTTP_CACHE_KEY_LEN; - - c->file.name.data = ngx_pnalloc(r->pool, c->file.name.len + 1); - if (c->file.name.data == NULL) { + if (ngx_http_file_cache_name(r, cache->path) != NGX_OK) { return NGX_ERROR; } - ngx_memcpy(c->file.name.data, path->name.data, path->name.len); - - p = c->file.name.data + path->name.len + 1 + path->len; - p = ngx_hex_dump(p, c->key, NGX_HTTP_CACHE_KEY_LEN); - *p = '\0'; - - ngx_create_hashed_filename(path, c->file.name.data, c->file.name.len); - - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "cache file: \"%s\"", c->file.name.data); - if (!test) { return NGX_DECLINED; } @@ -574,6 +611,37 @@ failed: } +static ngx_int_t +ngx_http_file_cache_name(ngx_http_request_t *r, ngx_path_t *path) +{ + u_char *p; + ngx_http_cache_t *c; + + c = r->cache; + + c->file.name.len = path->name.len + 1 + path->len + + 2 * NGX_HTTP_CACHE_KEY_LEN; + + c->file.name.data = ngx_pnalloc(r->pool, c->file.name.len + 1); + if (c->file.name.data == NULL) { + return NGX_ERROR; + } + + ngx_memcpy(c->file.name.data, path->name.data, path->name.len); + + p = c->file.name.data + path->name.len + 1 + path->len; + p = ngx_hex_dump(p, c->key, NGX_HTTP_CACHE_KEY_LEN); + *p = '\0'; + + ngx_create_hashed_filename(path, c->file.name.data, c->file.name.len); + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "cache file: \"%s\"", c->file.name.data); + + return NGX_OK; +} + + static ngx_http_file_cache_node_t * ngx_http_file_cache_lookup(ngx_http_file_cache_t *cache, u_char *key) { @@ -835,8 +903,9 @@ ngx_http_cache_send(ngx_http_request_t * void ngx_http_file_cache_free(ngx_http_request_t *r, ngx_temp_file_t *tf) { - ngx_http_cache_t *c; - ngx_http_file_cache_t *cache; + ngx_http_cache_t *c; + ngx_http_file_cache_t *cache; + ngx_http_file_cache_node_t *fcn; c = r->cache; @@ -853,16 +922,22 @@ ngx_http_file_cache_free(ngx_http_reques ngx_shmtx_lock(&cache->shpool->mutex); - c->node->count--; + fcn = c->node; + fcn->count--; + fcn->updating = 0; if (c->error) { - c->node->valid_sec = c->valid_sec; - c->node->valid_msec = c->valid_msec; - c->node->error = c->error; + fcn->valid_sec = c->valid_sec; + fcn->valid_msec = c->valid_msec; + fcn->error = c->error; + + } else if (fcn->valid_msec == 0 && fcn->count == 0) { + ngx_queue_remove(&fcn->queue); + ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); + ngx_slab_free_locked(cache->shpool, fcn); + c->node = NULL; } - c->node->updating = 0; - ngx_shmtx_unlock(&cache->shpool->mutex); if (c->temp_file) { @@ -1104,9 +1179,7 @@ ngx_http_file_cache_delete(ngx_http_file *p = '\0'; ngx_queue_remove(q); - ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); - ngx_slab_free_locked(cache->shpool, fcn); ngx_shmtx_unlock(&cache->shpool->mutex);