Mercurial > hg > nginx-vendor-0-8
comparison 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 |
comparison
equal
deleted
inserted
replaced
587:913af46ee783 | 588:b6a5942a4e6a |
---|---|
17 #if (NGX_HAVE_FILE_AIO) | 17 #if (NGX_HAVE_FILE_AIO) |
18 static void ngx_http_cache_aio_event_handler(ngx_event_t *ev); | 18 static void ngx_http_cache_aio_event_handler(ngx_event_t *ev); |
19 #endif | 19 #endif |
20 static ngx_int_t ngx_http_file_cache_exists(ngx_http_file_cache_t *cache, | 20 static ngx_int_t ngx_http_file_cache_exists(ngx_http_file_cache_t *cache, |
21 ngx_http_cache_t *c); | 21 ngx_http_cache_t *c); |
22 static ngx_int_t ngx_http_file_cache_name(ngx_http_request_t *r, | |
23 ngx_path_t *path); | |
22 static ngx_http_file_cache_node_t * | 24 static ngx_http_file_cache_node_t * |
23 ngx_http_file_cache_lookup(ngx_http_file_cache_t *cache, u_char *key); | 25 ngx_http_file_cache_lookup(ngx_http_file_cache_t *cache, u_char *key); |
24 static void ngx_http_file_cache_rbtree_insert_value(ngx_rbtree_node_t *temp, | 26 static void ngx_http_file_cache_rbtree_insert_value(ngx_rbtree_node_t *temp, |
25 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel); | 27 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel); |
26 static void ngx_http_file_cache_cleanup(void *data); | 28 static void ngx_http_file_cache_cleanup(void *data); |
42 ngx_str_t *path); | 44 ngx_str_t *path); |
43 | 45 |
44 | 46 |
45 ngx_str_t ngx_http_cache_status[] = { | 47 ngx_str_t ngx_http_cache_status[] = { |
46 ngx_string("MISS"), | 48 ngx_string("MISS"), |
49 ngx_string("BYPASS"), | |
47 ngx_string("EXPIRED"), | 50 ngx_string("EXPIRED"), |
48 ngx_string("STALE"), | 51 ngx_string("STALE"), |
49 ngx_string("UPDATING"), | 52 ngx_string("UPDATING"), |
50 ngx_string("HIT") | 53 ngx_string("HIT") |
51 }; | 54 }; |
140 | 143 |
141 return NGX_OK; | 144 return NGX_OK; |
142 } | 145 } |
143 | 146 |
144 | 147 |
148 ngx_int_t | |
149 ngx_http_file_cache_new(ngx_http_request_t *r) | |
150 { | |
151 ngx_http_cache_t *c; | |
152 | |
153 c = ngx_pcalloc(r->pool, sizeof(ngx_http_cache_t)); | |
154 if (c == NULL) { | |
155 return NGX_ERROR; | |
156 } | |
157 | |
158 if (ngx_array_init(&c->keys, r->pool, 4, sizeof(ngx_str_t)) != NGX_OK) { | |
159 return NGX_ERROR; | |
160 } | |
161 | |
162 r->cache = c; | |
163 c->file.log = r->connection->log; | |
164 | |
165 return NGX_OK; | |
166 } | |
167 | |
168 | |
169 ngx_int_t | |
170 ngx_http_file_cache_create(ngx_http_request_t *r) | |
171 { | |
172 ngx_http_cache_t *c; | |
173 ngx_pool_cleanup_t *cln; | |
174 ngx_http_file_cache_t *cache; | |
175 | |
176 ngx_http_file_cache_create_key(r); | |
177 | |
178 c = r->cache; | |
179 cache = c->file_cache; | |
180 | |
181 cln = ngx_pool_cleanup_add(r->pool, 0); | |
182 if (cln == NULL) { | |
183 return NGX_ERROR; | |
184 } | |
185 | |
186 if (ngx_http_file_cache_exists(cache, c) == NGX_ERROR) { | |
187 return NGX_ERROR; | |
188 } | |
189 | |
190 cln->handler = ngx_http_file_cache_cleanup; | |
191 cln->data = c; | |
192 | |
193 if (ngx_http_file_cache_name(r, cache->path) != NGX_OK) { | |
194 return NGX_ERROR; | |
195 } | |
196 | |
197 return NGX_OK; | |
198 } | |
199 | |
200 | |
145 void | 201 void |
146 ngx_http_file_cache_create_key(ngx_http_request_t *r) | 202 ngx_http_file_cache_create_key(ngx_http_request_t *r) |
147 { | 203 { |
148 size_t len; | 204 size_t len; |
149 ngx_str_t *key; | 205 ngx_str_t *key; |
178 | 234 |
179 | 235 |
180 ngx_int_t | 236 ngx_int_t |
181 ngx_http_file_cache_open(ngx_http_request_t *r) | 237 ngx_http_file_cache_open(ngx_http_request_t *r) |
182 { | 238 { |
183 u_char *p; | |
184 ngx_int_t rc, rv; | 239 ngx_int_t rc, rv; |
185 ngx_uint_t cold, test; | 240 ngx_uint_t cold, test; |
186 ngx_path_t *path; | |
187 ngx_http_cache_t *c; | 241 ngx_http_cache_t *c; |
188 ngx_pool_cleanup_t *cln; | 242 ngx_pool_cleanup_t *cln; |
189 ngx_open_file_info_t of; | 243 ngx_open_file_info_t of; |
190 ngx_http_file_cache_t *cache; | 244 ngx_http_file_cache_t *cache; |
191 ngx_http_core_loc_conf_t *clcf; | 245 ngx_http_core_loc_conf_t *clcf; |
247 test = cold ? 1 : 0; | 301 test = cold ? 1 : 0; |
248 rv = NGX_DECLINED; | 302 rv = NGX_DECLINED; |
249 } | 303 } |
250 } | 304 } |
251 | 305 |
252 path = cache->path; | 306 if (ngx_http_file_cache_name(r, cache->path) != NGX_OK) { |
253 | |
254 c->file.name.len = path->name.len + 1 + path->len | |
255 + 2 * NGX_HTTP_CACHE_KEY_LEN; | |
256 | |
257 c->file.name.data = ngx_pnalloc(r->pool, c->file.name.len + 1); | |
258 if (c->file.name.data == NULL) { | |
259 return NGX_ERROR; | 307 return NGX_ERROR; |
260 } | 308 } |
261 | |
262 ngx_memcpy(c->file.name.data, path->name.data, path->name.len); | |
263 | |
264 p = c->file.name.data + path->name.len + 1 + path->len; | |
265 p = ngx_hex_dump(p, c->key, NGX_HTTP_CACHE_KEY_LEN); | |
266 *p = '\0'; | |
267 | |
268 ngx_create_hashed_filename(path, c->file.name.data, c->file.name.len); | |
269 | |
270 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, | |
271 "cache file: \"%s\"", c->file.name.data); | |
272 | 309 |
273 if (!test) { | 310 if (!test) { |
274 return NGX_DECLINED; | 311 return NGX_DECLINED; |
275 } | 312 } |
276 | 313 |
572 | 609 |
573 return rc; | 610 return rc; |
574 } | 611 } |
575 | 612 |
576 | 613 |
614 static ngx_int_t | |
615 ngx_http_file_cache_name(ngx_http_request_t *r, ngx_path_t *path) | |
616 { | |
617 u_char *p; | |
618 ngx_http_cache_t *c; | |
619 | |
620 c = r->cache; | |
621 | |
622 c->file.name.len = path->name.len + 1 + path->len | |
623 + 2 * NGX_HTTP_CACHE_KEY_LEN; | |
624 | |
625 c->file.name.data = ngx_pnalloc(r->pool, c->file.name.len + 1); | |
626 if (c->file.name.data == NULL) { | |
627 return NGX_ERROR; | |
628 } | |
629 | |
630 ngx_memcpy(c->file.name.data, path->name.data, path->name.len); | |
631 | |
632 p = c->file.name.data + path->name.len + 1 + path->len; | |
633 p = ngx_hex_dump(p, c->key, NGX_HTTP_CACHE_KEY_LEN); | |
634 *p = '\0'; | |
635 | |
636 ngx_create_hashed_filename(path, c->file.name.data, c->file.name.len); | |
637 | |
638 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
639 "cache file: \"%s\"", c->file.name.data); | |
640 | |
641 return NGX_OK; | |
642 } | |
643 | |
644 | |
577 static ngx_http_file_cache_node_t * | 645 static ngx_http_file_cache_node_t * |
578 ngx_http_file_cache_lookup(ngx_http_file_cache_t *cache, u_char *key) | 646 ngx_http_file_cache_lookup(ngx_http_file_cache_t *cache, u_char *key) |
579 { | 647 { |
580 ngx_int_t rc; | 648 ngx_int_t rc; |
581 ngx_rbtree_key_t node_key; | 649 ngx_rbtree_key_t node_key; |
833 | 901 |
834 | 902 |
835 void | 903 void |
836 ngx_http_file_cache_free(ngx_http_request_t *r, ngx_temp_file_t *tf) | 904 ngx_http_file_cache_free(ngx_http_request_t *r, ngx_temp_file_t *tf) |
837 { | 905 { |
838 ngx_http_cache_t *c; | 906 ngx_http_cache_t *c; |
839 ngx_http_file_cache_t *cache; | 907 ngx_http_file_cache_t *cache; |
908 ngx_http_file_cache_node_t *fcn; | |
840 | 909 |
841 c = r->cache; | 910 c = r->cache; |
842 | 911 |
843 if (c->updated) { | 912 if (c->updated) { |
844 return; | 913 return; |
851 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 920 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
852 "http file cache free"); | 921 "http file cache free"); |
853 | 922 |
854 ngx_shmtx_lock(&cache->shpool->mutex); | 923 ngx_shmtx_lock(&cache->shpool->mutex); |
855 | 924 |
856 c->node->count--; | 925 fcn = c->node; |
926 fcn->count--; | |
927 fcn->updating = 0; | |
857 | 928 |
858 if (c->error) { | 929 if (c->error) { |
859 c->node->valid_sec = c->valid_sec; | 930 fcn->valid_sec = c->valid_sec; |
860 c->node->valid_msec = c->valid_msec; | 931 fcn->valid_msec = c->valid_msec; |
861 c->node->error = c->error; | 932 fcn->error = c->error; |
862 } | 933 |
863 | 934 } else if (fcn->valid_msec == 0 && fcn->count == 0) { |
864 c->node->updating = 0; | 935 ngx_queue_remove(&fcn->queue); |
936 ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); | |
937 ngx_slab_free_locked(cache->shpool, fcn); | |
938 c->node = NULL; | |
939 } | |
865 | 940 |
866 ngx_shmtx_unlock(&cache->shpool->mutex); | 941 ngx_shmtx_unlock(&cache->shpool->mutex); |
867 | 942 |
868 if (c->temp_file) { | 943 if (c->temp_file) { |
869 if (tf && tf->file.fd != NGX_INVALID_FILE) { | 944 if (tf && tf->file.fd != NGX_INVALID_FILE) { |
1102 len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t); | 1177 len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t); |
1103 p = ngx_hex_dump(p, fcn->key, len); | 1178 p = ngx_hex_dump(p, fcn->key, len); |
1104 *p = '\0'; | 1179 *p = '\0'; |
1105 | 1180 |
1106 ngx_queue_remove(q); | 1181 ngx_queue_remove(q); |
1107 | |
1108 ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); | 1182 ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); |
1109 | |
1110 ngx_slab_free_locked(cache->shpool, fcn); | 1183 ngx_slab_free_locked(cache->shpool, fcn); |
1111 | 1184 |
1112 ngx_shmtx_unlock(&cache->shpool->mutex); | 1185 ngx_shmtx_unlock(&cache->shpool->mutex); |
1113 | 1186 |
1114 len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN; | 1187 len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN; |