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;