comparison src/http/ngx_http_file_cache.c @ 592:09d5f308901f NGINX_0_8_48

nginx 0.8.48 *) Change: now the "server_name" directive default value is an empty name "". Thanks to Gena Makhomed. *) Change: now the "server_name_in_redirect" directive default value is "off". *) Feature: the $geoip_dma_code, $geoip_area_code, and $geoip_region_name variables. Thanks to Christine McGonagle. *) Bugfix: the "proxy_pass", "fastcgi_pass", "uwsgi_pass", and "scgi_pass" directives were not inherited inside "limit_except" blocks. *) Bugfix: the "proxy_cache_min_uses", "fastcgi_cache_min_uses" "uwsgi_cache_min_uses", and "scgi_cache_min_uses" directives did not work; the bug had appeared in 0.8.46. *) Bugfix: the "fastcgi_split_path_info" directive used incorrectly captures, if only parts of an URI were captured. Thanks to Yuriy Taraday and Frank Enderle. *) Bugfix: the "rewrite" directive did not escape a ";" character during copying from URI to query string. Thanks to Daisuke Murase. *) Bugfix: the ngx_http_image_filter_module closed a connection, if an image was larger than "image_filter_buffer" size.
author Igor Sysoev <http://sysoev.ru>
date Tue, 03 Aug 2010 00:00:00 +0400
parents cde3626b2d0d
children 3436cf38d59e
comparison
equal deleted inserted replaced
591:8b891ad58d6a 592:09d5f308901f
366 ssize_t n; 366 ssize_t n;
367 ngx_int_t rc; 367 ngx_int_t rc;
368 ngx_http_file_cache_t *cache; 368 ngx_http_file_cache_t *cache;
369 ngx_http_file_cache_header_t *h; 369 ngx_http_file_cache_header_t *h;
370 370
371 c = r->cache;
372
373 n = ngx_http_file_cache_aio_read(r, c); 371 n = ngx_http_file_cache_aio_read(r, c);
374 372
375 if (n < 0) { 373 if (n < 0) {
376 return n; 374 return n;
377 } 375 }
517 fcn = ngx_http_file_cache_lookup(cache, c->key); 515 fcn = ngx_http_file_cache_lookup(cache, c->key);
518 516
519 if (fcn) { 517 if (fcn) {
520 ngx_queue_remove(&fcn->queue); 518 ngx_queue_remove(&fcn->queue);
521 519
520 fcn->uses++;
521 fcn->count++;
522
522 if (fcn->error) { 523 if (fcn->error) {
523 524
524 if (fcn->valid_sec < ngx_time()) { 525 if (fcn->valid_sec < ngx_time()) {
525 goto renew; 526 goto renew;
526 } 527 }
527 528
528 rc = NGX_OK; 529 rc = NGX_OK;
529 530
530 goto done; 531 goto done;
531 } 532 }
532
533 fcn->uses++;
534 fcn->count++;
535 533
536 if (fcn->exists) { 534 if (fcn->exists) {
537 535
538 c->exists = fcn->exists; 536 c->exists = fcn->exists;
539 c->body_start = fcn->body_start; 537 c->body_start = fcn->body_start;
579 ngx_memcpy(fcn->key, &c->key[sizeof(ngx_rbtree_key_t)], 577 ngx_memcpy(fcn->key, &c->key[sizeof(ngx_rbtree_key_t)],
580 NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t)); 578 NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t));
581 579
582 ngx_rbtree_insert(&cache->sh->rbtree, &fcn->node); 580 ngx_rbtree_insert(&cache->sh->rbtree, &fcn->node);
583 581
584 renew:
585
586 rc = NGX_DECLINED;
587
588 fcn->uses = 1; 582 fcn->uses = 1;
589 fcn->count = 1; 583 fcn->count = 1;
584
585 renew:
586
587 rc = NGX_DECLINED;
588
590 fcn->valid_msec = 0; 589 fcn->valid_msec = 0;
591 fcn->error = 0; 590 fcn->error = 0;
592 fcn->exists = 0; 591 fcn->exists = 0;
593 fcn->valid_sec = 0; 592 fcn->valid_sec = 0;
594 fcn->uniq = 0; 593 fcn->uniq = 0;
930 if (c->error) { 929 if (c->error) {
931 fcn->valid_sec = c->valid_sec; 930 fcn->valid_sec = c->valid_sec;
932 fcn->valid_msec = c->valid_msec; 931 fcn->valid_msec = c->valid_msec;
933 fcn->error = c->error; 932 fcn->error = c->error;
934 933
935 } else if (!fcn->exists && fcn->count == 0) { 934 } else if (!fcn->exists && fcn->count == 0 && c->min_uses == 1) {
936 ngx_queue_remove(&fcn->queue); 935 ngx_queue_remove(&fcn->queue);
937 ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); 936 ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node);
938 ngx_slab_free_locked(cache->shpool, fcn); 937 ngx_slab_free_locked(cache->shpool, fcn);
939 c->node = NULL; 938 c->node = NULL;
940 } 939 }
1004 } 1003 }
1005 1004
1006 ngx_memcpy(name, path->name.data, path->name.len); 1005 ngx_memcpy(name, path->name.data, path->name.len);
1007 1006
1008 wait = 10; 1007 wait = 10;
1009 tries = 0; 1008 tries = 20;
1010 1009
1011 ngx_shmtx_lock(&cache->shpool->mutex); 1010 ngx_shmtx_lock(&cache->shpool->mutex);
1012 1011
1013 for (q = ngx_queue_last(&cache->sh->queue); 1012 for (q = ngx_queue_last(&cache->sh->queue);
1014 q != ngx_queue_sentinel(&cache->sh->queue); 1013 q != ngx_queue_sentinel(&cache->sh->queue);
1019 ngx_log_debug6(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, 1018 ngx_log_debug6(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
1020 "http file cache forced expire: #%d %d %02xd%02xd%02xd%02xd", 1019 "http file cache forced expire: #%d %d %02xd%02xd%02xd%02xd",
1021 fcn->count, fcn->exists, 1020 fcn->count, fcn->exists,
1022 fcn->key[0], fcn->key[1], fcn->key[2], fcn->key[3]); 1021 fcn->key[0], fcn->key[1], fcn->key[2], fcn->key[3]);
1023 1022
1024 if (fcn->count) { 1023 if (fcn->count == 0) {
1025 1024 ngx_http_file_cache_delete(cache, q, name);
1026 if (tries++ < 20) { 1025
1026 } else {
1027 if (--tries) {
1027 continue; 1028 continue;
1028 } 1029 }
1029 1030
1030 wait = 1; 1031 wait = 1;
1031 1032 }
1032 break;
1033 }
1034
1035 if (!fcn->exists) {
1036
1037 ngx_queue_remove(q);
1038 ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node);
1039 ngx_slab_free_locked(cache->shpool, fcn);
1040
1041 break;
1042 }
1043
1044 ngx_http_file_cache_delete(cache, q, name);
1045 1033
1046 break; 1034 break;
1047 } 1035 }
1048 1036
1049 ngx_shmtx_unlock(&cache->shpool->mutex); 1037 ngx_shmtx_unlock(&cache->shpool->mutex);
1103 ngx_log_debug6(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, 1091 ngx_log_debug6(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
1104 "http file cache expire: #%d %d %02xd%02xd%02xd%02xd", 1092 "http file cache expire: #%d %d %02xd%02xd%02xd%02xd",
1105 fcn->count, fcn->exists, 1093 fcn->count, fcn->exists,
1106 fcn->key[0], fcn->key[1], fcn->key[2], fcn->key[3]); 1094 fcn->key[0], fcn->key[1], fcn->key[2], fcn->key[3]);
1107 1095
1108 if (fcn->count) { 1096 if (fcn->count == 0) {
1109 1097 ngx_http_file_cache_delete(cache, q, name);
1110 p = ngx_hex_dump(key, (u_char *) &fcn->node.key,
1111 sizeof(ngx_rbtree_key_t));
1112
1113 len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t);
1114 (void) ngx_hex_dump(p, fcn->key, len);
1115
1116 /*
1117 * abnormally exited workers may leave locked cache entries,
1118 * and although it may be safe to remove them completely,
1119 * we prefer to remove them from inactive queue and rbtree
1120 * only, and to allow other leaks
1121 */
1122
1123 ngx_queue_remove(q);
1124 ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node);
1125
1126 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
1127 "ignore long locked inactive cache entry %*s, count:%d",
1128 2 * NGX_HTTP_CACHE_KEY_LEN, key, fcn->count);
1129
1130 continue; 1098 continue;
1131 } 1099 }
1132 1100
1133 if (!fcn->exists) { 1101 p = ngx_hex_dump(key, (u_char *) &fcn->node.key,
1134 1102 sizeof(ngx_rbtree_key_t));
1135 ngx_queue_remove(q); 1103 len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t);
1136 ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); 1104 (void) ngx_hex_dump(p, fcn->key, len);
1137 ngx_slab_free_locked(cache->shpool, fcn); 1105
1138 1106 /*
1139 continue; 1107 * abnormally exited workers may leave locked cache entries,
1140 } 1108 * and although it may be safe to remove them completely,
1141 1109 * we prefer to remove them from inactive queue and rbtree
1142 ngx_http_file_cache_delete(cache, q, name); 1110 * only, and to allow other leaks
1111 */
1112
1113 ngx_queue_remove(q);
1114 ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node);
1115
1116 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
1117 "ignore long locked inactive cache entry %*s, count:%d",
1118 2 * NGX_HTTP_CACHE_KEY_LEN, key, fcn->count);
1143 } 1119 }
1144 1120
1145 ngx_shmtx_unlock(&cache->shpool->mutex); 1121 ngx_shmtx_unlock(&cache->shpool->mutex);
1146 1122
1147 ngx_free(name); 1123 ngx_free(name);
1159 ngx_path_t *path; 1135 ngx_path_t *path;
1160 ngx_http_file_cache_node_t *fcn; 1136 ngx_http_file_cache_node_t *fcn;
1161 1137
1162 fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue); 1138 fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue);
1163 1139
1164 cache->sh->size -= (fcn->length + cache->bsize - 1) / cache->bsize; 1140 if (fcn->exists) {
1165 1141 cache->sh->size -= (fcn->length + cache->bsize - 1) / cache->bsize;
1166 path = cache->path; 1142
1167 1143 path = cache->path;
1168 p = name + path->name.len + 1 + path->len; 1144 p = name + path->name.len + 1 + path->len;
1169 1145 p = ngx_hex_dump(p, (u_char *) &fcn->node.key,
1170 p = ngx_hex_dump(p, (u_char *) &fcn->node.key, sizeof(ngx_rbtree_key_t)); 1146 sizeof(ngx_rbtree_key_t));
1171 1147 len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t);
1172 len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t); 1148 p = ngx_hex_dump(p, fcn->key, len);
1173 p = ngx_hex_dump(p, fcn->key, len); 1149 *p = '\0';
1174 *p = '\0'; 1150
1175 1151 fcn->count++;
1176 ngx_queue_remove(q); 1152 ngx_shmtx_unlock(&cache->shpool->mutex);
1177 ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); 1153
1178 ngx_slab_free_locked(cache->shpool, fcn); 1154 len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN;
1179 1155 ngx_create_hashed_filename(path, name, len);
1180 ngx_shmtx_unlock(&cache->shpool->mutex); 1156
1181 1157 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
1182 len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN; 1158 "http file cache expire: \"%s\"", name);
1183 1159
1184 ngx_create_hashed_filename(path, name, len); 1160 if (ngx_delete_file(name) == NGX_FILE_ERROR) {
1185 1161 ngx_log_error(NGX_LOG_CRIT, ngx_cycle->log, ngx_errno,
1186 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, 1162 ngx_delete_file_n " \"%s\" failed", name);
1187 "http file cache expire: \"%s\"", name); 1163 }
1188 1164
1189 if (ngx_delete_file(name) == NGX_FILE_ERROR) { 1165 ngx_shmtx_lock(&cache->shpool->mutex);
1190 ngx_log_error(NGX_LOG_CRIT, ngx_cycle->log, ngx_errno, 1166 fcn->count--;
1191 ngx_delete_file_n " \"%s\" failed", name); 1167 }
1192 } 1168
1193 1169 if (fcn->count == 0) {
1194 ngx_shmtx_lock(&cache->shpool->mutex); 1170 ngx_queue_remove(q);
1171 ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node);
1172 ngx_slab_free_locked(cache->shpool, fcn);
1173 }
1195 } 1174 }
1196 1175
1197 1176
1198 static time_t 1177 static time_t
1199 ngx_http_file_cache_manager(void *data) 1178 ngx_http_file_cache_manager(void *data)